diff options
241 files changed, 0 insertions, 72567 deletions
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub deleted file mode 100644 index 7213efb74d..0000000000 --- a/modules/assimp/SCsub +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_assimp = env_modules.Clone() - -# Thirdparty source files - -thirdparty_obj = [] - -# Force bundled version for now, there's no released version of Assimp with -# support for ArmaturePopulate which we use from their master branch. - -if True: # env['builtin_assimp']: - thirdparty_dir = "#thirdparty/assimp" - - env_assimp.Prepend(CPPPATH=["#thirdparty/assimp"]) - env_assimp.Prepend(CPPPATH=["#thirdparty/assimp/code"]) - env_assimp.Prepend(CPPPATH=["#thirdparty/assimp/include"]) - - # env_assimp.Append(CPPDEFINES=['ASSIMP_DOUBLE_PRECISION']) # TODO default to what godot is compiled with for future double support - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_SINGLETHREADED"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_BOOST_WORKAROUND"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OWN_ZLIB"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_EXPORT"]) - - # Importers we don't need - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_3D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_3DS_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_3MF_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_AC_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_AMF_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_ASE_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_ASSBIN_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_B3D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_BLEND_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_BVH_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_C4D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_COB_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_COLLADA_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_CSM_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_DXF_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_GLTF2_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_GLTF_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_HMP_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_IFC_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_IRR_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_IRRMESH_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_LWO_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_LWS_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_M3D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD2_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD3_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD5_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD5_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MDC_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MDL_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MMD_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MS3D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_NDO_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_NFF_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OBJ_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OFF_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OGRE_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OPENGEX_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_PLY_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_Q3BSP_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_Q3D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_RAW_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_SIB_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_SMD_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_STEP_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_STL_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_TERRAGEN_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_X3D_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_XGL_IMPORTER"]) - env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_X_IMPORTER"]) - - if env["platform"] == "windows": - env_assimp.Append(CPPDEFINES=["PLATFORM_WINDOWS"]) - env_assimp.Append(CPPDEFINES=[("PLATFORM", "WINDOWS")]) - elif env["platform"] == "linuxbsd": - env_assimp.Append(CPPDEFINES=["PLATFORM_LINUX"]) - env_assimp.Append(CPPDEFINES=[("PLATFORM", "LINUX")]) - elif env["platform"] == "osx": - env_assimp.Append(CPPDEFINES=["PLATFORM_DARWIN"]) - env_assimp.Append(CPPDEFINES=[("PLATFORM", "DARWIN")]) - - env_thirdparty = env_assimp.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/CApi/*.cpp")) - env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/Common/*.cpp")) - env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/PostProcessing/*.cpp")) - env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/Material/*.cpp")) - env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/FBX/*.cpp")) - env.modules_sources += thirdparty_obj - - -# Godot source files - -module_obj = [] - -env_assimp.add_source_files(module_obj, "*.cpp") -env.modules_sources += module_obj - -# Needed to force rebuilding the module files when the thirdparty library is updated. -env.Depends(module_obj, thirdparty_obj) diff --git a/modules/assimp/config.py b/modules/assimp/config.py deleted file mode 100644 index 53b8f2f2e3..0000000000 --- a/modules/assimp/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return env["tools"] - - -def configure(env): - pass diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp deleted file mode 100644 index 796ee27a7d..0000000000 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ /dev/null @@ -1,1485 +0,0 @@ -/*************************************************************************/ -/* editor_scene_importer_assimp.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "editor_scene_importer_assimp.h" -#include "core/io/image_loader.h" -#include "editor/import/resource_importer_scene.h" -#include "import_utils.h" -#include "scene/3d/camera_3d.h" -#include "scene/3d/light_3d.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/main/node.h" -#include "scene/resources/material.h" -#include "scene/resources/surface_tool.h" - -#include <assimp/matrix4x4.h> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/Importer.hpp> -#include <assimp/LogStream.hpp> - -// move into assimp -aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) { - for (unsigned int mesh_id = 0; mesh_id < scene->mNumMeshes; ++mesh_id) { - aiMesh *mesh = scene->mMeshes[mesh_id]; - - // iterate over all the bones on the mesh for this node only! - for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; boneIndex++) { - aiBone *bone = mesh->mBones[boneIndex]; - if (bone->mName == bone_name) { - printf("matched bone by name: %s\n", bone->mName.C_Str()); - return bone; - } - } - } - - return nullptr; -} - -void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const { - const String import_setting_string = "filesystem/import/open_asset_import/"; - - Map<String, ImportFormat> import_format; - { - Vector<String> exts; - exts.push_back("fbx"); - ImportFormat import = { exts, true }; - import_format.insert("fbx", import); - } - for (Map<String, ImportFormat>::Element *E = import_format.front(); E; E = E->next()) { - _register_project_setting_import(E->key(), import_setting_string, E->get().extensions, r_extensions, - E->get().is_default); - } -} - -void EditorSceneImporterAssimp::_register_project_setting_import(const String generic, const String import_setting_string, - const Vector<String> &exts, List<String> *r_extensions, - const bool p_enabled) const { - const String use_generic = "use_" + generic; - _GLOBAL_DEF(import_setting_string + use_generic, p_enabled, true); - if (ProjectSettings::get_singleton()->get(import_setting_string + use_generic)) { - for (int32_t i = 0; i < exts.size(); i++) { - r_extensions->push_back(exts[i]); - } - } -} - -uint32_t EditorSceneImporterAssimp::get_import_flags() const { - return IMPORT_SCENE; -} - -void EditorSceneImporterAssimp::_bind_methods() { -} - -Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, - List<String> *r_missing_deps, Error *r_err) { - Assimp::Importer importer; - importer.SetPropertyBool(AI_CONFIG_PP_FD_REMOVE, true); - // Cannot remove pivot points because the static mesh will be in the wrong place - importer.SetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, false); - int32_t max_bone_weights = 4; - //if (p_flags & IMPORT_ANIMATION_EIGHT_WEIGHTS) { - // const int eight_bones = 8; - // importer.SetPropertyBool(AI_CONFIG_PP_LBW_MAX_WEIGHTS, eight_bones); - // max_bone_weights = eight_bones; - //} - - importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT); - - //importer.SetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD, 1.0f); - int32_t post_process_Steps = aiProcess_CalcTangentSpace | - aiProcess_GlobalScale | - // imports models and listens to their file scale for CM to M conversions - //aiProcess_FlipUVs | - aiProcess_FlipWindingOrder | - // very important for culling so that it is done in the correct order. - //aiProcess_DropNormals | - //aiProcess_GenSmoothNormals | - //aiProcess_JoinIdenticalVertices | - aiProcess_ImproveCacheLocality | - //aiProcess_RemoveRedundantMaterials | // Causes a crash - //aiProcess_SplitLargeMeshes | - aiProcess_Triangulate | - aiProcess_GenUVCoords | - //aiProcess_FindDegenerates | - //aiProcess_SortByPType | - // aiProcess_FindInvalidData | - aiProcess_TransformUVCoords | - aiProcess_FindInstances | - //aiProcess_FixInfacingNormals | - //aiProcess_ValidateDataStructure | - aiProcess_OptimizeMeshes | - aiProcess_PopulateArmatureData | - //aiProcess_OptimizeGraph | - //aiProcess_Debone | - // aiProcess_EmbedTextures | - //aiProcess_SplitByBoneCount | - 0; - String g_path = ProjectSettings::get_singleton()->globalize_path(p_path); - aiScene *scene = (aiScene *)importer.ReadFile(g_path.utf8().ptr(), post_process_Steps); - - ERR_FAIL_COND_V_MSG(scene == nullptr, nullptr, String("Open Asset Import failed to open: ") + String(importer.GetErrorString())); - - return _generate_scene(p_path, scene, p_flags, p_bake_fps, max_bone_weights); -} - -template <class T> -struct EditorSceneImporterAssetImportInterpolate { - T lerp(const T &a, const T &b, float c) const { - return a + (b - a) * c; - } - - T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) { - float t2 = t * t; - float t3 = t2 * t; - - return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); - } - - T bezier(T start, T control_1, T control_2, T end, float t) { - /* Formula from Wikipedia article on Bezier curves. */ - real_t omt = (1.0 - t); - real_t omt2 = omt * omt; - real_t omt3 = omt2 * omt; - real_t t2 = t * t; - real_t t3 = t2 * t; - - return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3; - } -}; - -//thank you for existing, partial specialization -template <> -struct EditorSceneImporterAssetImportInterpolate<Quat> { - Quat lerp(const Quat &a, const Quat &b, float c) const { - ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quat(), "The quaternion \"a\" must be normalized."); - ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quat(), "The quaternion \"b\" must be normalized."); - - return a.slerp(b, c).normalized(); - } - - Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, float c) { - ERR_FAIL_COND_V_MSG(!p1.is_normalized(), Quat(), "The quaternion \"p1\" must be normalized."); - ERR_FAIL_COND_V_MSG(!p2.is_normalized(), Quat(), "The quaternion \"p2\" must be normalized."); - - return p1.slerp(p2, c).normalized(); - } - - Quat bezier(Quat start, Quat control_1, Quat control_2, Quat end, float t) { - ERR_FAIL_COND_V_MSG(!start.is_normalized(), Quat(), "The start quaternion must be normalized."); - ERR_FAIL_COND_V_MSG(!end.is_normalized(), Quat(), "The end quaternion must be normalized."); - - return start.slerp(end, t).normalized(); - } -}; - -template <class T> -T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, - AssetImportAnimation::Interpolation p_interp) { - //could use binary search, worth it? - int idx = -1; - for (int i = 0; i < p_times.size(); i++) { - if (p_times[i] > p_time) { - break; - } - idx++; - } - - EditorSceneImporterAssetImportInterpolate<T> interp; - - switch (p_interp) { - case AssetImportAnimation::INTERP_LINEAR: { - if (idx == -1) { - return p_values[0]; - } else if (idx >= p_times.size() - 1) { - return p_values[p_times.size() - 1]; - } - - float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]); - - return interp.lerp(p_values[idx], p_values[idx + 1], c); - - } break; - case AssetImportAnimation::INTERP_STEP: { - if (idx == -1) { - return p_values[0]; - } else if (idx >= p_times.size() - 1) { - return p_values[p_times.size() - 1]; - } - - return p_values[idx]; - - } break; - case AssetImportAnimation::INTERP_CATMULLROMSPLINE: { - if (idx == -1) { - return p_values[1]; - } else if (idx >= p_times.size() - 1) { - return p_values[1 + p_times.size() - 1]; - } - - float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]); - - return interp.catmull_rom(p_values[idx - 1], p_values[idx], p_values[idx + 1], p_values[idx + 3], c); - - } break; - case AssetImportAnimation::INTERP_CUBIC_SPLINE: { - if (idx == -1) { - return p_values[1]; - } else if (idx >= p_times.size() - 1) { - return p_values[(p_times.size() - 1) * 3 + 1]; - } - - float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]); - - T from = p_values[idx * 3 + 1]; - T c1 = from + p_values[idx * 3 + 2]; - T to = p_values[idx * 3 + 4]; - T c2 = to + p_values[idx * 3 + 3]; - - return interp.bezier(from, c1, c2, to, c); - - } break; - } - - ERR_FAIL_V(p_values[0]); -} - -aiBone *EditorSceneImporterAssimp::get_bone_from_stack(ImportState &state, aiString name) { - List<aiBone *>::Element *iter; - aiBone *bone = nullptr; - for (iter = state.bone_stack.front(); iter; iter = iter->next()) { - bone = (aiBone *)iter->get(); - - if (bone && bone->mName == name) { - state.bone_stack.erase(bone); - return bone; - } - } - - return nullptr; -} - -Node3D * -EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, - const int32_t p_max_bone_weights) { - ERR_FAIL_COND_V(scene == nullptr, nullptr); - - ImportState state; - state.path = p_path; - state.assimp_scene = scene; - state.max_bone_weights = p_max_bone_weights; - state.animation_player = nullptr; - state.import_flags = p_flags; - - // populate light map - for (unsigned int l = 0; l < scene->mNumLights; l++) { - aiLight *ai_light = scene->mLights[l]; - ERR_CONTINUE(ai_light == nullptr); - state.light_cache[AssimpUtils::get_assimp_string(ai_light->mName)] = l; - } - - // fill camera cache - for (unsigned int c = 0; c < scene->mNumCameras; c++) { - aiCamera *ai_camera = scene->mCameras[c]; - ERR_CONTINUE(ai_camera == nullptr); - state.camera_cache[AssimpUtils::get_assimp_string(ai_camera->mName)] = c; - } - - if (scene->mRootNode) { - state.nodes.push_back(scene->mRootNode); - - // make flat node tree - in order to make processing deterministic - for (unsigned int i = 0; i < scene->mRootNode->mNumChildren; i++) { - _generate_node(state, scene->mRootNode->mChildren[i]); - } - - RegenerateBoneStack(state); - - Node *last_valid_parent = nullptr; - - List<const aiNode *>::Element *iter; - for (iter = state.nodes.front(); iter; iter = iter->next()) { - const aiNode *element_assimp_node = iter->get(); - const aiNode *parent_assimp_node = element_assimp_node->mParent; - - String node_name = AssimpUtils::get_assimp_string(element_assimp_node->mName); - //print_verbose("node: " + node_name); - - Node3D *spatial = nullptr; - Transform transform = AssimpUtils::assimp_matrix_transform(element_assimp_node->mTransformation); - - // retrieve this node bone - aiBone *bone = get_bone_from_stack(state, element_assimp_node->mName); - - if (state.light_cache.has(node_name)) { - spatial = create_light(state, node_name, transform); - } else if (state.camera_cache.has(node_name)) { - spatial = create_camera(state, node_name, transform); - } else if (state.armature_nodes.find(element_assimp_node)) { - // create skeleton - print_verbose("Making skeleton: " + node_name); - Skeleton3D *skeleton = memnew(Skeleton3D); - spatial = skeleton; - if (!state.armature_skeletons.has(element_assimp_node)) { - state.armature_skeletons.insert(element_assimp_node, skeleton); - } - } else if (bone != nullptr) { - continue; - } else { - spatial = memnew(Node3D); - } - - ERR_CONTINUE_MSG(spatial == nullptr, "FBX Import - are we out of ram?"); - // we on purpose set the transform and name after creating the node. - - spatial->set_name(node_name); - spatial->set_global_transform(transform); - - // first element is root - if (iter == state.nodes.front()) { - state.root = spatial; - } - - // flat node map parent lookup tool - state.flat_node_map.insert(element_assimp_node, spatial); - - Map<const aiNode *, Node3D *>::Element *parent_lookup = state.flat_node_map.find(parent_assimp_node); - - // note: this always fails on the root node :) keep that in mind this is by design - if (parent_lookup) { - Node3D *parent_node = parent_lookup->value(); - - ERR_FAIL_COND_V_MSG(parent_node == nullptr, state.root, - "Parent node invalid even though lookup successful, out of ram?"); - - if (spatial != state.root) { - parent_node->add_child(spatial); - spatial->set_owner(state.root); - } else { - // required - think about it root never has a parent yet is valid, anything else without a parent is not valid. - } - } else if (spatial != state.root) { - // if the ainode is not in the tree - // parent it to the last good parent found - if (last_valid_parent) { - last_valid_parent->add_child(spatial); - spatial->set_owner(state.root); - } else { - // this is a serious error? - memdelete(spatial); - } - } - - // update last valid parent - last_valid_parent = spatial; - } - print_verbose("node counts: " + itos(state.nodes.size())); - - // make clean bone stack - RegenerateBoneStack(state); - - print_verbose("generating godot bone data"); - - print_verbose("Godot bone stack count: " + itos(state.bone_stack.size())); - - // This is a list of bones, duplicates are from other meshes and must be dealt with properly - for (List<aiBone *>::Element *element = state.bone_stack.front(); element; element = element->next()) { - aiBone *bone = element->get(); - - ERR_CONTINUE_MSG(!bone, "invalid bone read from assimp?"); - - // Utilities for armature lookup - for now only FBX makes these - aiNode *armature_for_bone = bone->mArmature; - - // Utilities for bone node lookup - for now only FBX makes these - aiNode *bone_node = bone->mNode; - aiNode *parent_node = bone_node->mParent; - - String bone_name = AssimpUtils::get_anim_string_from_assimp(bone->mName); - ERR_CONTINUE_MSG(armature_for_bone == nullptr, "Armature for bone invalid: " + bone_name); - Skeleton3D *skeleton = state.armature_skeletons[armature_for_bone]; - - state.skeleton_bone_map[bone] = skeleton; - - if (bone_name.empty()) { - bone_name = "untitled_bone_name"; - WARN_PRINT("Untitled bone name detected... report with file please"); - } - - // todo: this is where skin support goes - if (skeleton && skeleton->find_bone(bone_name) == -1) { - print_verbose("[Godot Glue] Imported bone" + bone_name); - int boneIdx = skeleton->get_bone_count(); - - Transform pform = AssimpUtils::assimp_matrix_transform(bone->mNode->mTransformation); - skeleton->add_bone(bone_name); - skeleton->set_bone_rest(boneIdx, pform); - - if (parent_node != nullptr) { - int parent_bone_id = skeleton->find_bone(AssimpUtils::get_anim_string_from_assimp(parent_node->mName)); - int current_bone_id = boneIdx; - skeleton->set_bone_parent(current_bone_id, parent_bone_id); - } - } - } - - print_verbose("generating mesh phase from skeletal mesh"); - - List<Node3D *> cleanup_template_nodes; - - for (Map<const aiNode *, Node3D *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) { - const aiNode *assimp_node = key_value_pair->key(); - Node3D *mesh_template = key_value_pair->value(); - - ERR_CONTINUE(assimp_node == nullptr); - ERR_CONTINUE(mesh_template == nullptr); - - Node *parent_node = mesh_template->get_parent(); - - if (mesh_template == state.root) { - continue; - } - - if (parent_node == nullptr) { - print_error("Found invalid parent node!"); - continue; // root node - } - - String node_name = AssimpUtils::get_assimp_string(assimp_node->mName); - Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation); - - if (assimp_node->mNumMeshes > 0) { - MeshInstance3D *mesh = create_mesh(state, assimp_node, node_name, parent_node, node_transform); - if (mesh) { - parent_node->remove_child(mesh_template); - - // re-parent children - List<Node *> children; - // re-parent all children to new node - // note: since get_child_count will change during execution we must build a list first to be safe. - for (int childId = 0; childId < mesh_template->get_child_count(); childId++) { - // get child - Node *child = mesh_template->get_child(childId); - children.push_back(child); - } - - for (List<Node *>::Element *element = children.front(); element; element = element->next()) { - // reparent the children to the real mesh node. - mesh_template->remove_child(element->get()); - mesh->add_child(element->get()); - element->get()->set_owner(state.root); - } - - // update mesh in list so that each mesh node is available - // this makes the template unavailable which is the desired behaviour - state.flat_node_map[assimp_node] = mesh; - - cleanup_template_nodes.push_back(mesh_template); - - // clean up this list we don't need it - children.clear(); - } - } - } - - for (List<Node3D *>::Element *element = cleanup_template_nodes.front(); element; element = element->next()) { - if (element->get()) { - memdelete(element->get()); - } - } - } - - if (p_flags & IMPORT_ANIMATION && scene->mNumAnimations) { - state.animation_player = memnew(AnimationPlayer); - state.root->add_child(state.animation_player); - state.animation_player->set_owner(state.root); - - for (uint32_t i = 0; i < scene->mNumAnimations; i++) { - _import_animation(state, i, p_bake_fps); - } - } - - // - // Cleanup operations - // - - state.mesh_cache.clear(); - state.material_cache.clear(); - state.light_cache.clear(); - state.camera_cache.clear(); - state.assimp_node_map.clear(); - state.path_to_image_cache.clear(); - state.nodes.clear(); - state.flat_node_map.clear(); - state.armature_skeletons.clear(); - state.bone_stack.clear(); - return state.root; -} - -void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id, - int anim_fps, Ref<Animation> animation, float ticks_per_second, - Skeleton3D *skeleton, const NodePath &node_path, - const String &node_name, aiBone *track_bone) { - const aiNodeAnim *assimp_track = assimp_anim->mChannels[track_id]; - //make transform track - int track_idx = animation->get_track_count(); - animation->add_track(Animation::TYPE_TRANSFORM); - animation->track_set_path(track_idx, node_path); - //first determine animation length - - float increment = 1.0 / float(anim_fps); - float time = 0.0; - - bool last = false; - - Vector<Vector3> pos_values; - Vector<float> pos_times; - Vector<Vector3> scale_values; - Vector<float> scale_times; - Vector<Quat> rot_values; - Vector<float> rot_times; - - for (size_t p = 0; p < assimp_track->mNumPositionKeys; p++) { - aiVector3D pos = assimp_track->mPositionKeys[p].mValue; - pos_values.push_back(Vector3(pos.x, pos.y, pos.z)); - pos_times.push_back(assimp_track->mPositionKeys[p].mTime / ticks_per_second); - } - - for (size_t r = 0; r < assimp_track->mNumRotationKeys; r++) { - aiQuaternion quat = assimp_track->mRotationKeys[r].mValue; - rot_values.push_back(Quat(quat.x, quat.y, quat.z, quat.w).normalized()); - rot_times.push_back(assimp_track->mRotationKeys[r].mTime / ticks_per_second); - } - - for (size_t sc = 0; sc < assimp_track->mNumScalingKeys; sc++) { - aiVector3D scale = assimp_track->mScalingKeys[sc].mValue; - scale_values.push_back(Vector3(scale.x, scale.y, scale.z)); - scale_times.push_back(assimp_track->mScalingKeys[sc].mTime / ticks_per_second); - } - - while (true) { - Vector3 pos; - Quat rot; - Vector3 scale(1, 1, 1); - - if (pos_values.size()) { - pos = _interpolate_track<Vector3>(pos_times, pos_values, time, AssetImportAnimation::INTERP_LINEAR); - } - - if (rot_values.size()) { - rot = _interpolate_track<Quat>(rot_times, rot_values, time, - AssetImportAnimation::INTERP_LINEAR) - .normalized(); - } - - if (scale_values.size()) { - scale = _interpolate_track<Vector3>(scale_times, scale_values, time, AssetImportAnimation::INTERP_LINEAR); - } - - if (skeleton) { - int skeleton_bone = skeleton->find_bone(node_name); - - if (skeleton_bone >= 0 && track_bone) { - Transform xform; - xform.basis.set_quat_scale(rot, scale); - xform.origin = pos; - - xform = skeleton->get_bone_rest(skeleton_bone).inverse() * xform; - - rot = xform.basis.get_rotation_quat(); - rot.normalize(); - scale = xform.basis.get_scale(); - pos = xform.origin; - } else { - ERR_FAIL_MSG("Skeleton bone lookup failed for skeleton: " + skeleton->get_name()); - } - } - - animation->track_set_interpolation_type(track_idx, Animation::INTERPOLATION_LINEAR); - animation->transform_track_insert_key(track_idx, time, pos, rot, scale); - - if (last) { //done this way so a key is always inserted past the end (for proper interpolation) - break; - } - time += increment; - if (time >= animation->get_length()) { - last = true; - } - } -} - -// I really do not like this but need to figure out a better way of removing it later. -Node *EditorSceneImporterAssimp::get_node_by_name(ImportState &state, String name) { - for (Map<const aiNode *, Node3D *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) { - const aiNode *assimp_node = key_value_pair->key(); - Node3D *node = key_value_pair->value(); - - String node_name = AssimpUtils::get_assimp_string(assimp_node->mName); - if (name == node_name && node) { - return node; - } - } - return nullptr; -} - -/* Bone stack is a fifo handler for multiple armatures since armatures aren't a thing in assimp (yet) */ -void EditorSceneImporterAssimp::RegenerateBoneStack(ImportState &state) { - state.bone_stack.clear(); - // build bone stack list - for (unsigned int mesh_id = 0; mesh_id < state.assimp_scene->mNumMeshes; ++mesh_id) { - aiMesh *mesh = state.assimp_scene->mMeshes[mesh_id]; - - // iterate over all the bones on the mesh for this node only! - for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; boneIndex++) { - aiBone *bone = mesh->mBones[boneIndex]; - - // doubtful this is required right now but best to check - if (!state.bone_stack.find(bone)) { - //print_verbose("[assimp] bone stack added: " + String(bone->mName.C_Str()) ); - state.bone_stack.push_back(bone); - } - } - } -} - -/* Bone stack is a fifo handler for multiple armatures since armatures aren't a thing in assimp (yet) */ -void EditorSceneImporterAssimp::RegenerateBoneStack(ImportState &state, aiMesh *mesh) { - state.bone_stack.clear(); - // iterate over all the bones on the mesh for this node only! - for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; boneIndex++) { - aiBone *bone = mesh->mBones[boneIndex]; - if (state.bone_stack.find(bone) == nullptr) { - state.bone_stack.push_back(bone); - } - } -} - -// animation tracks are per bone - -void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_animation_index, int p_bake_fps) { - ERR_FAIL_INDEX(p_animation_index, (int)state.assimp_scene->mNumAnimations); - - const aiAnimation *anim = state.assimp_scene->mAnimations[p_animation_index]; - String name = AssimpUtils::get_anim_string_from_assimp(anim->mName); - if (name == String()) { - name = "Animation " + itos(p_animation_index + 1); - } - print_verbose("import animation: " + name); - float ticks_per_second = anim->mTicksPerSecond; - - if (state.assimp_scene->mMetaData != nullptr && Math::is_equal_approx(ticks_per_second, 0.0f)) { - int32_t time_mode = 0; - state.assimp_scene->mMetaData->Get("TimeMode", time_mode); - ticks_per_second = AssimpUtils::get_fbx_fps(time_mode, state.assimp_scene); - } - - //? - //if ((p_path.get_file().get_extension().to_lower() == "glb" || p_path.get_file().get_extension().to_lower() == "gltf") && Math::is_equal_approx(ticks_per_second, 0.0f)) { - // ticks_per_second = 1000.0f; - //} - - if (Math::is_equal_approx(ticks_per_second, 0.0f)) { - ticks_per_second = 25.0f; - } - - Ref<Animation> animation; - animation.instance(); - animation->set_name(name); - animation->set_length(anim->mDuration / ticks_per_second); - - if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { - animation->set_loop(true); - } - - // generate bone stack for animation import - RegenerateBoneStack(state); - - //regular tracks - for (size_t i = 0; i < anim->mNumChannels; i++) { - const aiNodeAnim *track = anim->mChannels[i]; - String node_name = AssimpUtils::get_assimp_string(track->mNodeName); - print_verbose("track name import: " + node_name); - if (track->mNumRotationKeys == 0 && track->mNumPositionKeys == 0 && track->mNumScalingKeys == 0) { - continue; //do not bother - } - - Skeleton3D *skeleton = nullptr; - NodePath node_path; - aiBone *bone = nullptr; - - // Import skeleton bone animation for this track - // Any bone will do, no point in processing more than just what is in the skeleton - { - bone = get_bone_from_stack(state, track->mNodeName); - - if (bone) { - // get skeleton by bone - skeleton = state.armature_skeletons[bone->mArmature]; - - if (skeleton) { - String path = state.root->get_path_to(skeleton); - path += ":" + node_name; - node_path = path; - - if (node_path != NodePath()) { - _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton, - node_path, node_name, bone); - } else { - print_error("Failed to find valid node path for animation"); - } - } - } - } - - // not a bone - // note this is flaky it uses node names which is unreliable - Node *allocated_node = get_node_by_name(state, node_name); - // todo: implement skeleton grabbing for node based animations too :) - // check if node exists, if it does then also apply animation track for node and bones above are all handled. - // this is now inclusive animation handling so that - // we import all the data and do not miss anything. - if (allocated_node) { - node_path = state.root->get_path_to(allocated_node); - - if (node_path != NodePath()) { - _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton, - node_path, node_name, nullptr); - } - } - } - - //blend shape tracks - - for (size_t i = 0; i < anim->mNumMorphMeshChannels; i++) { - const aiMeshMorphAnim *anim_mesh = anim->mMorphMeshChannels[i]; - - const String prop_name = AssimpUtils::get_assimp_string(anim_mesh->mName); - const String mesh_name = prop_name.split("*")[0]; - - ERR_CONTINUE(prop_name.split("*").size() != 2); - - Node *item = get_node_by_name(state, mesh_name); - ERR_CONTINUE_MSG(!item, "failed to look up node by name"); - const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(item); - ERR_CONTINUE(mesh_instance == nullptr); - - String base_path = state.root->get_path_to(mesh_instance); - - Ref<Mesh> mesh = mesh_instance->get_mesh(); - ERR_CONTINUE(mesh.is_null()); - - //add the tracks for this mesh - int base_track = animation->get_track_count(); - for (int j = 0; j < mesh->get_blend_shape_count(); j++) { - animation->add_track(Animation::TYPE_VALUE); - animation->track_set_path(base_track + j, base_path + ":blend_shapes/" + mesh->get_blend_shape_name(j)); - } - - for (size_t k = 0; k < anim_mesh->mNumKeys; k++) { - for (size_t j = 0; j < anim_mesh->mKeys[k].mNumValuesAndWeights; j++) { - float t = anim_mesh->mKeys[k].mTime / ticks_per_second; - float w = anim_mesh->mKeys[k].mWeights[j]; - - animation->track_insert_key(base_track + j, t, w); - } - } - } - - if (animation->get_track_count()) { - state.animation_player->add_animation(name, animation); - } -} - -// -// Mesh Generation from indices ? why do we need so much mesh code -// [debt needs looked into] -Ref<Mesh> -EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, - const aiNode *assimp_node, Ref<Skin> &skin, - Skeleton3D *&skeleton_assigned) { - Ref<ArrayMesh> mesh; - mesh.instance(); - bool has_uvs = false; - uint32_t mesh_flags = 0; - - Map<String, uint32_t> morph_mesh_string_lookup; - - for (int i = 0; i < p_surface_indices.size(); i++) { - const unsigned int mesh_idx = p_surface_indices[0]; - const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx]; - for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) { - String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName); - if (!morph_mesh_string_lookup.has(ai_anim_mesh_name)) { - morph_mesh_string_lookup.insert(ai_anim_mesh_name, j); - mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED); - if (ai_anim_mesh_name.empty()) { - ai_anim_mesh_name = String("morph_") + itos(j); - } - mesh->add_blend_shape(ai_anim_mesh_name); - } - } - } - // - // Process Vertex Weights - // - for (int i = 0; i < p_surface_indices.size(); i++) { - const unsigned int mesh_idx = p_surface_indices[i]; - const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx]; - - Map<uint32_t, Vector<BoneInfo>> vertex_weights; - - if (ai_mesh->mNumBones > 0) { - for (size_t b = 0; b < ai_mesh->mNumBones; b++) { - aiBone *bone = ai_mesh->mBones[b]; - - if (!skeleton_assigned) { - print_verbose("Assigned mesh skeleton during mesh creation"); - skeleton_assigned = state.skeleton_bone_map[bone]; - - if (!skin.is_valid()) { - print_verbose("Configured new skin"); - skin.instance(); - } else { - print_verbose("Reusing existing skin!"); - } - } - // skeleton_assigned = - String bone_name = AssimpUtils::get_assimp_string(bone->mName); - int bone_index = skeleton_assigned->find_bone(bone_name); - ERR_CONTINUE(bone_index == -1); - for (size_t w = 0; w < bone->mNumWeights; w++) { - aiVertexWeight ai_weights = bone->mWeights[w]; - - BoneInfo bi; - uint32_t vertex_index = ai_weights.mVertexId; - bi.bone = bone_index; - bi.weight = ai_weights.mWeight; - - if (!vertex_weights.has(vertex_index)) { - vertex_weights[vertex_index] = Vector<BoneInfo>(); - } - - vertex_weights[vertex_index].push_back(bi); - } - } - } - - // - // Create mesh from data from assimp - // - - Ref<SurfaceTool> st; - st.instance(); - st->begin(Mesh::PRIMITIVE_TRIANGLES); - - for (size_t j = 0; j < ai_mesh->mNumVertices; j++) { - // Get the texture coordinates if they exist - if (ai_mesh->HasTextureCoords(0)) { - has_uvs = true; - st->set_uv(Vector2(ai_mesh->mTextureCoords[0][j].x, 1.0f - ai_mesh->mTextureCoords[0][j].y)); - } - - if (ai_mesh->HasTextureCoords(1)) { - has_uvs = true; - st->set_uv2(Vector2(ai_mesh->mTextureCoords[1][j].x, 1.0f - ai_mesh->mTextureCoords[1][j].y)); - } - - // Assign vertex colors - if (ai_mesh->HasVertexColors(0)) { - Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b, - ai_mesh->mColors[0]->a); - st->set_color(color); - } - - // Work out normal calculations? - this needs work it doesn't work properly on huestos - if (ai_mesh->mNormals != nullptr) { - const aiVector3D normals = ai_mesh->mNormals[j]; - const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z); - st->set_normal(godot_normal); - if (ai_mesh->HasTangentsAndBitangents()) { - const aiVector3D tangents = ai_mesh->mTangents[j]; - const Vector3 godot_tangent = Vector3(tangents.x, tangents.y, tangents.z); - const aiVector3D bitangent = ai_mesh->mBitangents[j]; - const Vector3 godot_bitangent = Vector3(bitangent.x, bitangent.y, bitangent.z); - float d = godot_normal.cross(godot_tangent).dot(godot_bitangent) > 0.0f ? 1.0f : -1.0f; - st->set_tangent(Plane(tangents.x, tangents.y, tangents.z, d)); - } - } - - // We have vertex weights right? - if (vertex_weights.has(j)) { - Vector<BoneInfo> bone_info = vertex_weights[j]; - Vector<int> bones; - bones.resize(bone_info.size()); - Vector<float> weights; - weights.resize(bone_info.size()); - - // todo? do we really need to loop over all bones? - assimp may have helper to find all influences on this vertex. - for (int k = 0; k < bone_info.size(); k++) { - bones.write[k] = bone_info[k].bone; - weights.write[k] = bone_info[k].weight; - } - - st->set_bones(bones); - st->set_weights(weights); - } - - // Assign vertex - const aiVector3D pos = ai_mesh->mVertices[j]; - - // note we must include node offset transform as this is relative to world space not local space. - Vector3 godot_pos = Vector3(pos.x, pos.y, pos.z); - st->add_vertex(godot_pos); - } - - // fire replacement for face handling - for (size_t j = 0; j < ai_mesh->mNumFaces; j++) { - const aiFace face = ai_mesh->mFaces[j]; - for (unsigned int k = 0; k < face.mNumIndices; k++) { - st->add_index(face.mIndices[k]); - } - } - - if (ai_mesh->HasTangentsAndBitangents() == false && has_uvs) { - st->generate_tangents(); - } - - aiMaterial *ai_material = state.assimp_scene->mMaterials[ai_mesh->mMaterialIndex]; - Ref<StandardMaterial3D> mat; - mat.instance(); - - int32_t mat_two_sided = 0; - if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) { - if (mat_two_sided > 0) { - mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); - } else { - mat->set_cull_mode(StandardMaterial3D::CULL_BACK); - } - } - - aiString mat_name; - if (AI_SUCCESS == ai_material->Get(AI_MATKEY_NAME, mat_name)) { - mat->set_name(AssimpUtils::get_assimp_string(mat_name)); - } - - // Culling handling for meshes - - // cull all back faces - mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); - - // Now process materials - aiTextureType base_color = aiTextureType_BASE_COLOR; - { - String filename, path; - AssimpImageData image_data; - - if (AssimpUtils::GetAssimpTexture(state, ai_material, base_color, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - - // anything transparent must be culled - if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { - mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); - mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode - } - - mat->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, image_data.texture); - } - } - - aiTextureType tex_diffuse = aiTextureType_DIFFUSE; - { - String filename, path; - AssimpImageData image_data; - - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_diffuse, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - - // anything transparent must be culled - if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { - mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); - mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode - } - - mat->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, image_data.texture); - } - - aiColor4D clr_diffuse; - if (AI_SUCCESS == ai_material->Get(AI_MATKEY_COLOR_DIFFUSE, clr_diffuse)) { - if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) { - mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); - mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode - } - mat->set_albedo(Color(clr_diffuse.r, clr_diffuse.g, clr_diffuse.b, clr_diffuse.a)); - } - } - - aiTextureType tex_normal = aiTextureType_NORMALS; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); - } else { - aiString texture_path; - if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_NORMAL_TEXTURE, AI_PROPERTIES, texture_path)) { - if (AssimpUtils::CreateAssimpTexture(state, texture_path, filename, path, image_data)) { - mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); - } - } - } - } - - aiTextureType tex_normal_camera = aiTextureType_NORMAL_CAMERA; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); - } - } - - aiTextureType tex_emission_color = aiTextureType_EMISSION_COLOR; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); - } - } - - aiTextureType tex_metalness = aiTextureType_METALNESS; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(StandardMaterial3D::TEXTURE_METALLIC, image_data.texture); - } - } - - aiTextureType tex_roughness = aiTextureType_DIFFUSE_ROUGHNESS; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(StandardMaterial3D::TEXTURE_ROUGHNESS, image_data.texture); - } - } - - aiTextureType tex_emissive = aiTextureType_EMISSIVE; - { - String filename = ""; - String path = ""; - Ref<Image> texture; - AssimpImageData image_data; - - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emissive, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(StandardMaterial3D::FEATURE_EMISSION, true); - mat->set_texture(StandardMaterial3D::TEXTURE_EMISSION, image_data.texture); - } else { - // Process emission textures - aiString texture_emissive_path; - if (AI_SUCCESS == - ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE, AI_PROPERTIES, texture_emissive_path)) { - if (AssimpUtils::CreateAssimpTexture(state, texture_emissive_path, filename, path, image_data)) { - mat->set_feature(StandardMaterial3D::FEATURE_EMISSION, true); - mat->set_texture(StandardMaterial3D::TEXTURE_EMISSION, image_data.texture); - } - } else { - float pbr_emission = 0.0f; - if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSIVE_FACTOR, AI_NULL, pbr_emission)) { - mat->set_emission(Color(pbr_emission, pbr_emission, pbr_emission, 1.0f)); - } - } - } - } - - aiTextureType tex_specular = aiTextureType_SPECULAR; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_specular, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(StandardMaterial3D::TEXTURE_METALLIC, image_data.texture); - } - } - - aiTextureType tex_ao_map = aiTextureType_AMBIENT_OCCLUSION; - { - String filename, path; - Ref<ImageTexture> texture; - AssimpImageData image_data; - - // Process texture normal map - if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_ao_map, filename, path, image_data)) { - AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(StandardMaterial3D::FEATURE_AMBIENT_OCCLUSION, true); - mat->set_texture(StandardMaterial3D::TEXTURE_AMBIENT_OCCLUSION, image_data.texture); - } - } - - Array array_mesh = st->commit_to_arrays(); - Array morphs; - morphs.resize(ai_mesh->mNumAnimMeshes); - Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES; - - for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) { - String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName); - - if (ai_anim_mesh_name.empty()) { - ai_anim_mesh_name = String("morph_") + itos(j); - } - - Array array_copy; - array_copy.resize(RenderingServer::ARRAY_MAX); - - for (int l = 0; l < RenderingServer::ARRAY_MAX; l++) { - array_copy[l] = array_mesh[l].duplicate(true); - } - - const size_t num_vertices = ai_mesh->mAnimMeshes[j]->mNumVertices; - array_copy[Mesh::ARRAY_INDEX] = Variant(); - if (ai_mesh->mAnimMeshes[j]->HasPositions()) { - PackedVector3Array vertices; - vertices.resize(num_vertices); - for (size_t l = 0; l < num_vertices; l++) { - const aiVector3D ai_pos = ai_mesh->mAnimMeshes[j]->mVertices[l]; - Vector3 position = Vector3(ai_pos.x, ai_pos.y, ai_pos.z); - vertices.ptrw()[l] = position; - } - PackedVector3Array new_vertices = array_copy[RenderingServer::ARRAY_VERTEX].duplicate(true); - ERR_CONTINUE(vertices.size() != new_vertices.size()); - for (int32_t l = 0; l < new_vertices.size(); l++) { - Vector3 *w = new_vertices.ptrw(); - w[l] = vertices[l]; - } - array_copy[RenderingServer::ARRAY_VERTEX] = new_vertices; - } - - int32_t color_set = 0; - if (ai_mesh->mAnimMeshes[j]->HasVertexColors(color_set)) { - PackedColorArray colors; - colors.resize(num_vertices); - for (size_t l = 0; l < num_vertices; l++) { - const aiColor4D ai_color = ai_mesh->mAnimMeshes[j]->mColors[color_set][l]; - Color color = Color(ai_color.r, ai_color.g, ai_color.b, ai_color.a); - colors.ptrw()[l] = color; - } - PackedColorArray new_colors = array_copy[RenderingServer::ARRAY_COLOR].duplicate(true); - ERR_CONTINUE(colors.size() != new_colors.size()); - for (int32_t l = 0; l < colors.size(); l++) { - Color *w = new_colors.ptrw(); - w[l] = colors[l]; - } - array_copy[RenderingServer::ARRAY_COLOR] = new_colors; - } - - if (ai_mesh->mAnimMeshes[j]->HasNormals()) { - PackedVector3Array normals; - normals.resize(num_vertices); - for (size_t l = 0; l < num_vertices; l++) { - const aiVector3D ai_normal = ai_mesh->mAnimMeshes[j]->mNormals[l]; - Vector3 normal = Vector3(ai_normal.x, ai_normal.y, ai_normal.z); - normals.ptrw()[l] = normal; - } - PackedVector3Array new_normals = array_copy[RenderingServer::ARRAY_NORMAL].duplicate(true); - ERR_CONTINUE(normals.size() != new_normals.size()); - for (int l = 0; l < normals.size(); l++) { - Vector3 *w = new_normals.ptrw(); - w[l] = normals[l]; - } - array_copy[RenderingServer::ARRAY_NORMAL] = new_normals; - } - - if (ai_mesh->mAnimMeshes[j]->HasTangentsAndBitangents()) { - PackedColorArray tangents; - tangents.resize(num_vertices); - Color *w = tangents.ptrw(); - for (size_t l = 0; l < num_vertices; l++) { - AssimpUtils::calc_tangent_from_mesh(ai_mesh, j, l, l, w); - } - PackedFloat32Array new_tangents = array_copy[RenderingServer::ARRAY_TANGENT].duplicate(true); - ERR_CONTINUE(new_tangents.size() != tangents.size() * 4); - for (int32_t l = 0; l < tangents.size(); l++) { - new_tangents.ptrw()[l + 0] = tangents[l].r; - new_tangents.ptrw()[l + 1] = tangents[l].g; - new_tangents.ptrw()[l + 2] = tangents[l].b; - new_tangents.ptrw()[l + 3] = tangents[l].a; - } - array_copy[RenderingServer::ARRAY_TANGENT] = new_tangents; - } - - morphs[j] = array_copy; - } - mesh->add_surface_from_arrays(primitive, array_mesh, morphs, Dictionary(), mesh_flags); - mesh->surface_set_material(i, mat); - mesh->surface_set_name(i, AssimpUtils::get_assimp_string(ai_mesh->mName)); - } - - return mesh; -} - -/** - * Create a new mesh for the node supplied - */ -MeshInstance3D * -EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform) { - /* MESH NODE */ - Ref<Mesh> mesh; - Ref<Skin> skin; - // see if we have mesh cache for this. - Vector<int> surface_indices; - - RegenerateBoneStack(state); - - // Configure indices - for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) { - int mesh_index = assimp_node->mMeshes[i]; - // create list of mesh indexes - surface_indices.push_back(mesh_index); - } - - //surface_indices.sort(); - String mesh_key; - for (int i = 0; i < surface_indices.size(); i++) { - if (i > 0) { - mesh_key += ":"; - } - mesh_key += itos(surface_indices[i]); - } - - Skeleton3D *skeleton = nullptr; - aiNode *armature = nullptr; - - if (!state.mesh_cache.has(mesh_key)) { - mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skin, skeleton); - state.mesh_cache[mesh_key] = mesh; - } - - MeshInstance3D *mesh_node = memnew(MeshInstance3D); - mesh = state.mesh_cache[mesh_key]; - mesh_node->set_mesh(mesh); - - // if we have a valid skeleton set it up - if (skin.is_valid()) { - for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) { - unsigned int mesh_index = assimp_node->mMeshes[i]; - const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_index]; - - // please remember bone id relative to the skin is NOT the mesh relative index. - // it is the index relative to the skeleton that is why - // we have state.bone_id_map, it allows for duplicate bone id's too :) - // hope this makes sense - - int bind_count = 0; - for (unsigned int boneId = 0; boneId < ai_mesh->mNumBones; ++boneId) { - aiBone *iterBone = ai_mesh->mBones[boneId]; - - // used to reparent mesh to the correct armature later on if assigned. - if (!armature) { - print_verbose("Configured mesh armature, will reparent later to armature"); - armature = iterBone->mArmature; - } - - if (skeleton) { - int id = skeleton->find_bone(AssimpUtils::get_assimp_string(iterBone->mName)); - if (id != -1) { - print_verbose("Set bind bone: mesh: " + itos(mesh_index) + " bone index: " + itos(id)); - Transform t = AssimpUtils::assimp_matrix_transform(iterBone->mOffsetMatrix); - - skin->add_bind(bind_count, t); - skin->set_bind_bone(bind_count, id); - bind_count++; - } - } - } - } - - print_verbose("Finished configuring bind pose for skin mesh"); - } - - // this code parents all meshes with bones to the armature they are for - // GLTF2 specification relies on this and we are enforcing it for FBX. - if (armature && state.flat_node_map[armature]) { - Node *armature_parent = state.flat_node_map[armature]; - print_verbose("Parented mesh " + node_name + " to armature " + armature_parent->get_name()); - // static mesh handling - armature_parent->add_child(mesh_node); - // transform must be identity - mesh_node->set_global_transform(Transform()); - mesh_node->set_name(node_name); - mesh_node->set_owner(state.root); - } else { - // static mesh handling - active_node->add_child(mesh_node); - mesh_node->set_global_transform(node_transform); - mesh_node->set_name(node_name); - mesh_node->set_owner(state.root); - } - - if (skeleton) { - print_verbose("Attempted to set skeleton path!"); - mesh_node->set_skeleton_path(mesh_node->get_path_to(skeleton)); - mesh_node->set_skin(skin); - } - - return mesh_node; -} - -/** - * Create a light for the scene - * Automatically caches lights for lookup later - */ -Node3D *EditorSceneImporterAssimp::create_light( - ImportState &state, - const String &node_name, - Transform &look_at_transform) { - Light3D *light = nullptr; - aiLight *assimp_light = state.assimp_scene->mLights[state.light_cache[node_name]]; - ERR_FAIL_COND_V(!assimp_light, nullptr); - - if (assimp_light->mType == aiLightSource_DIRECTIONAL) { - light = memnew(DirectionalLight3D); - } else if (assimp_light->mType == aiLightSource_POINT) { - light = memnew(OmniLight3D); - } else if (assimp_light->mType == aiLightSource_SPOT) { - light = memnew(SpotLight3D); - } - ERR_FAIL_COND_V(light == nullptr, nullptr); - - if (assimp_light->mType != aiLightSource_POINT) { - Vector3 pos = Vector3( - assimp_light->mPosition.x, - assimp_light->mPosition.y, - assimp_light->mPosition.z); - Vector3 look_at = Vector3( - assimp_light->mDirection.y, - assimp_light->mDirection.x, - assimp_light->mDirection.z) - .normalized(); - Vector3 up = Vector3( - assimp_light->mUp.x, - assimp_light->mUp.y, - assimp_light->mUp.z); - - look_at_transform.set_look_at(pos, look_at, up); - } - // properties for light variables should be put here. - // not really hugely important yet but we will need them in the future - - light->set_color( - Color(assimp_light->mColorDiffuse.r, assimp_light->mColorDiffuse.g, assimp_light->mColorDiffuse.b)); - - return light; -} - -/** - * Create camera for the scene - */ -Node3D *EditorSceneImporterAssimp::create_camera( - ImportState &state, - const String &node_name, - Transform &look_at_transform) { - aiCamera *camera = state.assimp_scene->mCameras[state.camera_cache[node_name]]; - ERR_FAIL_COND_V(!camera, nullptr); - - Camera3D *camera_node = memnew(Camera3D); - ERR_FAIL_COND_V(!camera_node, nullptr); - float near = camera->mClipPlaneNear; - if (Math::is_equal_approx(near, 0.0f)) { - near = 0.1f; - } - camera_node->set_perspective(Math::rad2deg(camera->mHorizontalFOV) * 2.0f, near, camera->mClipPlaneFar); - Vector3 pos = Vector3(camera->mPosition.x, camera->mPosition.y, camera->mPosition.z); - Vector3 look_at = Vector3(camera->mLookAt.y, camera->mLookAt.x, camera->mLookAt.z).normalized(); - Vector3 up = Vector3(camera->mUp.x, camera->mUp.y, camera->mUp.z); - - look_at_transform.set_look_at(pos + look_at_transform.origin, look_at, up); - return camera_node; -} - -/** - * Generate node - * Recursive call to iterate over all nodes - */ -void EditorSceneImporterAssimp::_generate_node( - ImportState &state, - const aiNode *assimp_node) { - ERR_FAIL_COND(assimp_node == nullptr); - state.nodes.push_back(assimp_node); - String parent_name = AssimpUtils::get_assimp_string(assimp_node->mParent->mName); - - // please note - // duplicate bone names exist - // this is why we only check if the bone exists - // so everything else is useless but the name - // please do not copy any other values from get_bone_by_name. - aiBone *parent_bone = get_bone_by_name(state.assimp_scene, assimp_node->mParent->mName); - aiBone *current_bone = get_bone_by_name(state.assimp_scene, assimp_node->mName); - - // is this an armature - // parent null - // and this is the first bone :) - if (parent_bone == nullptr && current_bone) { - state.armature_nodes.push_back(assimp_node->mParent); - print_verbose("found valid armature: " + parent_name); - } - - for (size_t i = 0; i < assimp_node->mNumChildren; i++) { - _generate_node(state, assimp_node->mChildren[i]); - } -} diff --git a/modules/assimp/editor_scene_importer_assimp.h b/modules/assimp/editor_scene_importer_assimp.h deleted file mode 100644 index 80bba6ad66..0000000000 --- a/modules/assimp/editor_scene_importer_assimp.h +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************/ -/* editor_scene_importer_assimp.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef EDITOR_SCENE_IMPORTER_ASSIMP_H -#define EDITOR_SCENE_IMPORTER_ASSIMP_H - -#ifdef TOOLS_ENABLED -#include "core/core_bind.h" -#include "core/io/resource_importer.h" -#include "core/templates/vector.h" -#include "editor/import/resource_importer_scene.h" -#include "editor/project_settings_editor.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/node_3d.h" -#include "scene/3d/skeleton_3d.h" -#include "scene/animation/animation_player.h" -#include "scene/resources/animation.h" -#include "scene/resources/surface_tool.h" - -#include <assimp/matrix4x4.h> -#include <assimp/scene.h> -#include <assimp/types.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/LogStream.hpp> -#include <assimp/Logger.hpp> -#include <map> - -#include "import_state.h" -#include "import_utils.h" - -using namespace AssimpImporter; - -class AssimpStream : public Assimp::LogStream { -public: - // Constructor - AssimpStream() {} - - // Destructor - ~AssimpStream() {} - // Write something using your own functionality - void write(const char *message) { - print_verbose(String("Open Asset Import: ") + String(message).strip_edges()); - } -}; - -class EditorSceneImporterAssimp : public EditorSceneImporter { -private: - GDCLASS(EditorSceneImporterAssimp, EditorSceneImporter); - - struct AssetImportAnimation { - enum Interpolation { - INTERP_LINEAR, - INTERP_STEP, - INTERP_CATMULLROMSPLINE, - INTERP_CUBIC_SPLINE - }; - }; - - struct BoneInfo { - uint32_t bone; - float weight; - }; - - Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, - const aiNode *assimp_node, Ref<Skin> &skin, - Skeleton3D *&skeleton_assigned); - - // simple object creation functions - Node3D *create_light(ImportState &state, - const String &node_name, - Transform &look_at_transform); - Node3D *create_camera( - ImportState &state, - const String &node_name, - Transform &look_at_transform); - // non recursive - linear so must not use recursive arguments - MeshInstance3D *create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform); - // recursive node generator - void _generate_node(ImportState &state, const aiNode *assimp_node); - void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id, - int anim_fps, Ref<Animation> animation, float ticks_per_second, - Skeleton3D *skeleton, const NodePath &node_path, - const String &node_name, aiBone *track_bone); - - void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps); - Node *get_node_by_name(ImportState &state, String name); - aiBone *get_bone_from_stack(ImportState &state, aiString name); - Node3D *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights); - - template <class T> - T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp); - void _register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, const bool p_enabled) const; - - struct ImportFormat { - Vector<String> extensions; - bool is_default; - }; - -protected: - static void _bind_methods(); - -public: - EditorSceneImporterAssimp() { - Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE); - unsigned int severity = Assimp::Logger::Info | Assimp::Logger::Err | Assimp::Logger::Warn; - Assimp::DefaultLogger::get()->attachStream(new AssimpStream(), severity); - } - ~EditorSceneImporterAssimp() { - Assimp::DefaultLogger::kill(); - } - - virtual void get_extensions(List<String> *r_extensions) const override; - virtual uint32_t get_import_flags() const override; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; - Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path); - - static void RegenerateBoneStack(ImportState &state); - - void RegenerateBoneStack(ImportState &state, aiMesh *mesh); -}; -#endif -#endif diff --git a/modules/assimp/godot_update_assimp.sh b/modules/assimp/godot_update_assimp.sh deleted file mode 100755 index ff8ff59e97..0000000000 --- a/modules/assimp/godot_update_assimp.sh +++ /dev/null @@ -1,262 +0,0 @@ -rm -rf ../../thirdparty/assimp -cd ../../thirdparty/ -git clone https://github.com/assimp/assimp.git -cd assimp -rm -rf code/3DSExporter.h -rm -rf code/3DSLoader.h -rm -rf code/3MFXmlTags.h -rm -rf code/ABCImporter.h -rm -rf code/ACLoader.h -rm -rf code/AMFImporter_Macro.hpp -rm -rf code/ASELoader.h -rm -rf code/assbin_chunks.h -rm -rf code/AssbinExporter.h -rm -rf code/AssbinLoader.h -rm -rf code/AssimpCExport.cpp -rm -rf code/AssxmlExporter.h -rm -rf code/B3DImporter.h -# rm -rf code/BaseProcess.cpp -# rm -rf code/BaseProcess.h -# rm -rf code/Bitmap.cpp -rm -rf code/BlenderBMesh.cpp -rm -rf code/BlenderBMesh.h -rm -rf code/BlenderCustomData.cpp -rm -rf code/BlenderCustomData.h -rm -rf code/BlenderIntermediate.h -rm -rf code/BlenderLoader.h -rm -rf code/BlenderModifier.h -rm -rf code/BlenderSceneGen.h -rm -rf code/BlenderTessellator.h -rm -rf code/BVHLoader.h -rm -rf code/C4DImporter.h -# rm -rf code/CalcTangentsProcess.h -# rm -rf code/CInterfaceIOWrapper.cpp -# rm -rf code/CInterfaceIOWrapper.h -rm -rf code/COBLoader.h -rm -rf code/COBScene.h -rm -rf code/ColladaExporter.h -rm -rf code/ColladaLoader.h -# rm -rf code/ComputeUVMappingProcess.h -# rm -rf code/ConvertToLHProcess.h -# rm -rf code/CreateAnimMesh.cpp -rm -rf code/CSMLoader.h -rm -rf code/D3MFExporter.h -rm -rf code/D3MFImporter.h -rm -rf code/D3MFOpcPackage.h -# rm -rf code/DeboneProcess.h -# rm -rf code/DefaultIOStream.cpp -# rm -rf code/DefaultIOSystem.cpp -# rm -rf code/DefaultProgressHandler.h -# rm -rf code/DropFaceNormalsProcess.cpp -# rm -rf code/DropFaceNormalsProcess.h -rm -rf code/DXFHelper.h -rm -rf code/DXFLoader.h -# rm -rf code/EmbedTexturesProcess.cpp -# rm -rf code/EmbedTexturesProcess.h -# rm -rf code/FBXCommon.h -# rm -rf code/FBXCompileConfig.h -# rm -rf code/FBXDeformer.cpp -# rm -rf code/FBXDocumentUtil.cpp -# rm -rf code/FBXDocumentUtil.h -# rm -rf code/FBXExporter.h -# rm -rf code/FBXExportNode.h -# rm -rf code/FBXExportProperty.h -# rm -rf code/FBXImporter.cpp -# rm -rf code/FBXImporter.h -# rm -rf code/FBXImportSettings.h -# rm -rf code/FBXMeshGeometry.h -# rm -rf code/FBXModel.cpp -# rm -rf code/FBXNodeAttribute.cpp -# rm -rf code/FBXParser.h -# rm -rf code/FBXProperties.cpp -# rm -rf code/FBXProperties.h -# rm -rf code/FBXTokenizer.cpp -# rm -rf code/FBXTokenizer.h -# rm -rf code/FBXUtil.cpp -# rm -rf code/FBXUtil.h -# rm -rf code/FileLogStream.h -# rm -rf code/FindDegenerates.h -# rm -rf code/FindInstancesProcess.h -# rm -rf code/FindInvalidDataProcess.h -rm -rf code/FIReader.hpp -# rm -rf code/FixNormalsStep.cpp -# rm -rf code/FixNormalsStep.h -# rm -rf code/GenFaceNormalsProcess.cpp -# rm -rf code/GenFaceNormalsProcess.h -# rm -rf code/GenVertexNormalsProcess.cpp -# rm -rf code/GenVertexNormalsProcess.h -rm -rf code/glTF2Asset.h -rm -rf code/glTF2Asset.inl -rm -rf code/glTF2AssetWriter.inl -rm -rf code/glTF2Exporter.cpp -rm -rf code/glTF2Importer.cpp -rm -rf code/glTF2AssetWriter.h -rm -rf code/glTFAsset.h -rm -rf code/glTFAsset.inl -rm -rf code/glTFAssetWriter.inl -rm -rf code/glTFExporter.cpp -rm -rf code/glTFImporter.cpp -rm -rf code/glTF2Exporter.h -rm -rf code/glTF2Importer.h -rm -rf code/glTFAssetWriter.h -rm -rf code/glTFExporter.h -rm -rf code/glTFImporter.h -rm -rf code/HalfLifeFileData.h -rm -rf code/HMPFileData.h -rm -rf code/HMPLoader.h -rm -rf code/HMPLoader.cpp -rm -rf code/IFF.h -# rm -rf code/Importer.h -# rm -rf code/ImproveCacheLocality.h -rm -rf code/IRRLoader.h -rm -rf code/IRRMeshLoader.h -rm -rf code/IRRShared.h -# rm -rf code/JoinVerticesProcess.h -# rm -rf code/LimitBoneWeightsProcess.cpp -# rm -rf code/LimitBoneWeightsProcess.h -rm -rf code/LWSLoader.h -rm -rf code/makefile.mingw -# rm -rf code/MakeVerboseFormat.cpp -# rm -rf code/MakeVerboseFormat.h -# rm -rf code/MaterialSystem.h -rm -rf code/MD2FileData.h -rm -rf code/MD2Loader.h -rm -rf code/MD2NormalTable.h -rm -rf code/MD3FileData.h -rm -rf code/MD3Loader.h -rm -rf code/MD4FileData.h -rm -rf code/MD5Loader.h -rm -rf code/MD5Parser.cpp -rm -rf code/MDCFileData.h -rm -rf code/MDCLoader.h -rm -rf code/MDLDefaultColorMap.h -# rm -rf code/MMDCpp14.h -# rm -rf code/MMDImporter.h -rm -rf code/MS3DLoader.h -rm -rf code/NDOLoader.h -rm -rf code/NFFLoader.h -rm -rf code/ObjExporter.h -rm -rf code/ObjFileImporter.h -rm -rf code/ObjFileMtlImporter.h -rm -rf code/ObjFileParser.h -rm -rf code/ObjTools.h -rm -rf code/ObjExporter.cpp -rm -rf code/ObjFileImporter.cpp -rm -rf code/ObjFileMtlImporter.cpp -rm -rf code/ObjFileParser.cpp -rm -rf code/OFFLoader.h -rm -rf code/OFFLoader.cpp -rm -rf code/OgreImporter.cpp -rm -rf code/OgreImporter.h -rm -rf code/OgreParsingUtils.h -rm -rf code/OgreXmlSerializer.h -rm -rf code/OgreXmlSerializer.cpp -rm -rf code/OgreBinarySerializer.cpp -rm -rf code/OpenGEXExporter.cpp -rm -rf code/OpenGEXExporter.h -rm -rf code/OpenGEXImporter.h -rm -rf code/OpenGEXStructs.h -rm -rf code/OpenGEXImporter.cpp -# rm -rf code/OptimizeGraph.h -# rm -rf code/OptimizeMeshes.cpp -# rm -rf code/OptimizeMeshes.h -rm -rf code/PlyExporter.h -rm -rf code/PlyLoader.h -# rm -rf code/PolyTools.h -# rm -rf code/PostStepRegistry.cpp -# rm -rf code/PretransformVertices.h -rm -rf code/Q3BSPFileData.h -rm -rf code/Q3BSPFileImporter.h -rm -rf code/Q3BSPFileParser.cpp -rm -rf code/Q3BSPFileParser.h -rm -rf code/Q3BSPZipArchive.cpp -rm -rf code/Q3BSPZipArchive.h -rm -rf code/Q3DLoader.h -rm -rf code/Q3DLoader.cpp -rm -rf code/Q3BSPFileImporter.cpp -rm -rf code/RawLoader.h -# rm -rf code/RemoveComments.cpp -# rm -rf code/RemoveRedundantMaterials.cpp -# rm -rf code/RemoveRedundantMaterials.h -# rm -rf code/RemoveVCProcess.h -# rm -rf code/ScaleProcess.cpp -# rm -rf code/ScaleProcess.h -# rm -rf code/scene.cpp -# rm -rf code/ScenePreprocessor.cpp -# rm -rf code/ScenePreprocessor.h -# rm -rf code/ScenePrivate.h -# rm -rf code/SGSpatialSort.cpp -rm -rf code/SIBImporter.h -rm -rf code/SMDLoader.cpp -# rm -rf code/simd.cpp -# rm -rf code/simd.h -# rm -rf code/SortByPTypeProcess.h -# rm -rf code/SplitByBoneCountProcess.h -# rm -rf code/SplitLargeMeshes.h -# rm -rf code/StdOStreamLogStream.h -rm -rf code/StepExporter.h -rm -rf code/StepExporter.cpp -rm -rf code/STLExporter.cpp -rm -rf code/STLExporter.h -rm -rf code/STLLoader.h -rm -rf code/STLLoader.cpp -# rm -rf code/TargetAnimation.cpp -# rm -rf code/TargetAnimation.h -rm -rf code/TerragenLoader.h -rm -rf code/TerragenLoader.cpp -# rm -rf code/TextureTransform.h -# rm -rf code/TriangulateProcess.h -rm -rf code/UnrealLoader.h -# rm -rf code/ValidateDataStructure.h -# rm -rf code/Version.cpp -# rm -rf code/VertexTriangleAdjacency.cpp -# rm -rf code/VertexTriangleAdjacency.h -# rm -rf code/Win32DebugLogStream.h -rm -rf code/X3DImporter_Macro.hpp -rm -rf code/X3DImporter_Metadata.cpp -rm -rf code/X3DImporter_Networking.cpp -rm -rf code/X3DImporter_Texturing.cpp -rm -rf code/X3DImporter_Shape.cpp -rm -rf code/X3DImporter_Rendering.cpp -rm -rf code/X3DImporter_Postprocess.cpp -rm -rf code/X3DImporter_Light.cpp -rm -rf code/X3DImporter_Group.cpp -rm -rf code/X3DImporter_Geometry3D.cpp -rm -rf code/X3DImporter_Geometry2D.cpp -rm -rf code/X3DImporter.cpp -rm -rf code/X3DExporter.cpp -rm -rf code/X3DVocabulary.cpp -rm -rf code/XFileExporter.h -rm -rf code/XFileExporter.cpp -rm -rf code/XFileHelper.h -rm -rf code/XFileHelper.cpp -rm -rf code/XFileImporter.h -rm -rf code/XFileImporter.cpp -rm -rf code/XFileParser.h -rm -rf code/XFileParser.cpp -rm -rf code/XGLLoader.h -rm -rf code/XGLLoader.cpp -rm -rf code/Importer -rm -rf .git -rm -rf cmake-modules -rm -rf doc -rm -rf packaging -rm -rf port -rm -rf samples -rm -rf scripts -rm -rf test -rm -rf tools -rm -rf contrib/zlib -rm -rf contrib/android-cmake -rm -rf contrib/gtest -rm -rf contrib/clipper -rm -rf contrib/irrXML -rm -rf contrib/Open3DGC -rm -rf contrib/openddlparser -rm -rf contrib/poly2tri -#rm -rf contrib/rapidjson -rm -rf contrib/unzip -rm -rf contrib/zip -rm -rf contrib/stb_image -rm .travis* - diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h deleted file mode 100644 index a1cce6968b..0000000000 --- a/modules/assimp/import_state.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************/ -/* import_state.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef EDITOR_SCENE_IMPORT_STATE_H -#define EDITOR_SCENE_IMPORT_STATE_H - -#include "core/core_bind.h" -#include "core/io/resource_importer.h" -#include "core/templates/vector.h" -#include "editor/import/resource_importer_scene.h" -#include "editor/project_settings_editor.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/node_3d.h" -#include "scene/3d/skeleton_3d.h" -#include "scene/animation/animation_player.h" -#include "scene/resources/animation.h" -#include "scene/resources/surface_tool.h" - -#include <assimp/matrix4x4.h> -#include <assimp/scene.h> -#include <assimp/types.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/LogStream.hpp> -#include <assimp/Logger.hpp> - -namespace AssimpImporter { -/** Import state is for global scene import data - * This makes the code simpler and contains useful lookups. - */ -struct ImportState { - String path; - Node3D *root; - const aiScene *assimp_scene; - uint32_t max_bone_weights; - - Map<String, Ref<Mesh>> mesh_cache; - Map<int, Ref<Material>> material_cache; - Map<String, int> light_cache; - Map<String, int> camera_cache; - - // very useful for when you need to ask assimp for the bone mesh - - Map<const aiNode *, Node *> assimp_node_map; - Map<String, Ref<Image>> path_to_image_cache; - - // Generation 3 - determinisitic iteration - // to lower potential recursion errors - List<const aiNode *> nodes; - Map<const aiNode *, Node3D *> flat_node_map; - AnimationPlayer *animation_player; - - // Generation 3 - deterministic armatures - // list of armature nodes - flat and simple to parse - // assimp node, node in godot - List<aiNode *> armature_nodes; - Map<const aiNode *, Skeleton3D *> armature_skeletons; - Map<aiBone *, Skeleton3D *> skeleton_bone_map; - // Generation 3 - deterministic bone handling - // bones from the stack are popped when found - // this means we can detect - // what bones are for other armatures - List<aiBone *> bone_stack; - - // EditorSceneImporter::ImportFlags - uint32_t import_flags; -}; - -struct AssimpImageData { - Ref<Image> raw_image; - Ref<ImageTexture> texture; - aiTextureMapMode map_mode[2]; -}; - -/** Recursive state is used to push state into functions instead of specifying them - * This makes the code easier to handle too and add extra arguments without breaking things - */ -struct RecursiveState { - RecursiveState() {} // do not construct :) - RecursiveState( - Transform &_node_transform, - Skeleton3D *_skeleton, - Node3D *_new_node, - String &_node_name, - aiNode *_assimp_node, - Node *_parent_node, - aiBone *_bone) : - node_transform(_node_transform), - skeleton(_skeleton), - new_node(_new_node), - node_name(_node_name), - assimp_node(_assimp_node), - parent_node(_parent_node), - bone(_bone) {} - - Transform node_transform; - Skeleton3D *skeleton = nullptr; - Node3D *new_node = nullptr; - String node_name; - aiNode *assimp_node = nullptr; - Node *parent_node = nullptr; - aiBone *bone = nullptr; -}; -} // namespace AssimpImporter - -#endif // EDITOR_SCENE_IMPORT_STATE_H diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h deleted file mode 100644 index dc85d06fed..0000000000 --- a/modules/assimp/import_utils.h +++ /dev/null @@ -1,463 +0,0 @@ -/*************************************************************************/ -/* import_utils.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef IMPORT_UTILS_IMPORTER_ASSIMP_H -#define IMPORT_UTILS_IMPORTER_ASSIMP_H - -#include "core/io/image_loader.h" -#include "import_state.h" - -#include <assimp/SceneCombiner.h> -#include <assimp/cexport.h> -#include <assimp/cimport.h> -#include <assimp/matrix4x4.h> -#include <assimp/pbrmaterial.h> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/Importer.hpp> -#include <assimp/LogStream.hpp> -#include <assimp/Logger.hpp> -#include <string> - -using namespace AssimpImporter; - -#define AI_PROPERTIES aiTextureType_UNKNOWN, 0 -#define AI_NULL 0, 0 -#define AI_MATKEY_FBX_MAYA_BASE_COLOR_FACTOR "$raw.Maya|baseColor" -#define AI_MATKEY_FBX_MAYA_METALNESS_FACTOR "$raw.Maya|metalness" -#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_FACTOR "$raw.Maya|diffuseRoughness" - -#define AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE "$raw.Maya|emissionColor|file" -#define AI_MATKEY_FBX_MAYA_EMISSIVE_FACTOR "$raw.Maya|emission" -#define AI_MATKEY_FBX_MAYA_METALNESS_TEXTURE "$raw.Maya|metalness|file" -#define AI_MATKEY_FBX_MAYA_METALNESS_UV_XFORM "$raw.Maya|metalness|uvtrafo" -#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_TEXTURE "$raw.Maya|diffuseRoughness|file" -#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_UV_XFORM "$raw.Maya|diffuseRoughness|uvtrafo" -#define AI_MATKEY_FBX_MAYA_BASE_COLOR_TEXTURE "$raw.Maya|baseColor|file" -#define AI_MATKEY_FBX_MAYA_BASE_COLOR_UV_XFORM "$raw.Maya|baseColor|uvtrafo" -#define AI_MATKEY_FBX_MAYA_NORMAL_TEXTURE "$raw.Maya|normalCamera|file" -#define AI_MATKEY_FBX_MAYA_NORMAL_UV_XFORM "$raw.Maya|normalCamera|uvtrafo" - -#define AI_MATKEY_FBX_NORMAL_TEXTURE "$raw.Maya|normalCamera|file" -#define AI_MATKEY_FBX_NORMAL_UV_XFORM "$raw.Maya|normalCamera|uvtrafo" - -#define AI_MATKEY_FBX_MAYA_STINGRAY_DISPLACEMENT_SCALING_FACTOR "$raw.Maya|displacementscaling" -#define AI_MATKEY_FBX_MAYA_STINGRAY_BASE_COLOR_FACTOR "$raw.Maya|base_color" -#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_FACTOR "$raw.Maya|emissive" -#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_FACTOR "$raw.Maya|metallic" -#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_FACTOR "$raw.Maya|roughness" -#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_INTENSITY_FACTOR "$raw.Maya|emissive_intensity" - -#define AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_TEXTURE "$raw.Maya|TEX_normal_map|file" -#define AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_UV_XFORM "$raw.Maya|TEX_normal_map|uvtrafo" -#define AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_TEXTURE "$raw.Maya|TEX_color_map|file" -#define AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_UV_XFORM "$raw.Maya|TEX_color_map|uvtrafo" -#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_TEXTURE "$raw.Maya|TEX_metallic_map|file" -#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_UV_XFORM "$raw.Maya|TEX_metallic_map|uvtrafo" -#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_TEXTURE "$raw.Maya|TEX_roughness_map|file" -#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_UV_XFORM "$raw.Maya|TEX_roughness_map|uvtrafo" -#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_TEXTURE "$raw.Maya|TEX_emissive_map|file" -#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_UV_XFORM "$raw.Maya|TEX_emissive_map|uvtrafo" -#define AI_MATKEY_FBX_MAYA_STINGRAY_AO_TEXTURE "$raw.Maya|TEX_ao_map|file" -#define AI_MATKEY_FBX_MAYA_STINGRAY_AO_UV_XFORM "$raw.Maya|TEX_ao_map|uvtrafo" - -/** - * Assimp Utils - * Conversion tools / glue code to convert from assimp to godot -*/ -class AssimpUtils { -public: - /** - * calculate tangents for mesh data from assimp data - */ - static void calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, Color *w) { - const aiVector3D normals = ai_mesh->mAnimMeshes[i]->mNormals[tri_index]; - const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z); - const aiVector3D tangent = ai_mesh->mAnimMeshes[i]->mTangents[tri_index]; - const Vector3 godot_tangent = Vector3(tangent.x, tangent.y, tangent.z); - const aiVector3D bitangent = ai_mesh->mAnimMeshes[i]->mBitangents[tri_index]; - const Vector3 godot_bitangent = Vector3(bitangent.x, bitangent.y, bitangent.z); - float d = godot_normal.cross(godot_tangent).dot(godot_bitangent) > 0.0f ? 1.0f : -1.0f; - Color plane_tangent = Color(tangent.x, tangent.y, tangent.z, d); - w[index] = plane_tangent; - } - - struct AssetImportFbx { - enum ETimeMode { - TIME_MODE_DEFAULT = 0, - TIME_MODE_120 = 1, - TIME_MODE_100 = 2, - TIME_MODE_60 = 3, - TIME_MODE_50 = 4, - TIME_MODE_48 = 5, - TIME_MODE_30 = 6, - TIME_MODE_30_DROP = 7, - TIME_MODE_NTSC_DROP_FRAME = 8, - TIME_MODE_NTSC_FULL_FRAME = 9, - TIME_MODE_PAL = 10, - TIME_MODE_CINEMA = 11, - TIME_MODE_1000 = 12, - TIME_MODE_CINEMA_ND = 13, - TIME_MODE_CUSTOM = 14, - TIME_MODE_TIME_MODE_COUNT = 15 - }; - enum UpAxis { - UP_VECTOR_AXIS_X = 1, - UP_VECTOR_AXIS_Y = 2, - UP_VECTOR_AXIS_Z = 3 - }; - enum FrontAxis { - FRONT_PARITY_EVEN = 1, - FRONT_PARITY_ODD = 2, - }; - - enum CoordAxis { - COORD_RIGHT = 0, - COORD_LEFT = 1 - }; - }; - - /** Get assimp string - * automatically filters the string data - */ - static String get_assimp_string(const aiString &p_string) { - //convert an assimp String to a Godot String - String name; - name.parse_utf8(p_string.C_Str() /*,p_string.length*/); - if (name.find(":") != -1) { - String replaced_name = name.split(":")[1]; - print_verbose("Replacing " + name + " containing : with " + replaced_name); - name = replaced_name; - } - - return name; - } - - static String get_anim_string_from_assimp(const aiString &p_string) { - String name; - name.parse_utf8(p_string.C_Str() /*,p_string.length*/); - if (name.find(":") != -1) { - String replaced_name = name.split(":")[1]; - print_verbose("Replacing " + name + " containing : with " + replaced_name); - name = replaced_name; - } - return name; - } - - /** - * No filter logic get_raw_string_from_assimp - * This just convers the aiString to a parsed utf8 string - * Without removing special chars etc - */ - static String get_raw_string_from_assimp(const aiString &p_string) { - String name; - name.parse_utf8(p_string.C_Str() /*,p_string.length*/); - return name; - } - - static Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) { - return Ref<Animation>(); - } - - /** - * Converts aiMatrix4x4 to godot Transform - */ - static const Transform assimp_matrix_transform(const aiMatrix4x4 p_matrix) { - aiMatrix4x4 matrix = p_matrix; - Transform xform; - xform.set(matrix.a1, matrix.a2, matrix.a3, matrix.b1, matrix.b2, matrix.b3, matrix.c1, matrix.c2, matrix.c3, matrix.a4, matrix.b4, matrix.c4); - return xform; - } - - /** Get fbx fps for time mode meta data - */ - static float get_fbx_fps(int32_t time_mode, const aiScene *p_scene) { - switch (time_mode) { - case AssetImportFbx::TIME_MODE_DEFAULT: - return 24; //hack - case AssetImportFbx::TIME_MODE_120: - return 120; - case AssetImportFbx::TIME_MODE_100: - return 100; - case AssetImportFbx::TIME_MODE_60: - return 60; - case AssetImportFbx::TIME_MODE_50: - return 50; - case AssetImportFbx::TIME_MODE_48: - return 48; - case AssetImportFbx::TIME_MODE_30: - return 30; - case AssetImportFbx::TIME_MODE_30_DROP: - return 30; - case AssetImportFbx::TIME_MODE_NTSC_DROP_FRAME: - return 29.9700262f; - case AssetImportFbx::TIME_MODE_NTSC_FULL_FRAME: - return 29.9700262f; - case AssetImportFbx::TIME_MODE_PAL: - return 25; - case AssetImportFbx::TIME_MODE_CINEMA: - return 24; - case AssetImportFbx::TIME_MODE_1000: - return 1000; - case AssetImportFbx::TIME_MODE_CINEMA_ND: - return 23.976f; - case AssetImportFbx::TIME_MODE_CUSTOM: - int32_t frame_rate = -1; - p_scene->mMetaData->Get("FrameRate", frame_rate); - return frame_rate; - } - return 0; - } - - /** - * Get global transform for the current node - so we can use world space rather than - * local space coordinates - * useful if you need global - although recommend using local wherever possible over global - * as you could break fbx scaling :) - */ - static Transform _get_global_assimp_node_transform(const aiNode *p_current_node) { - aiNode const *current_node = p_current_node; - Transform xform; - while (current_node != nullptr) { - xform = assimp_matrix_transform(current_node->mTransformation) * xform; - current_node = current_node->mParent; - } - return xform; - } - - /** - * Find hardcoded textures from assimp which could be in many different directories - */ - static void find_texture_path(const String &p_path, _Directory &dir, String &path, bool &found, String extension) { - Vector<String> paths; - paths.push_back(path.get_basename() + extension); - paths.push_back(path + extension); - paths.push_back(path); - paths.push_back(p_path.get_base_dir().plus_file(path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file(path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file(path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("textures/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("textures/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("textures/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("Textures/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("Textures/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("Textures/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("../Textures/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../Textures/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../Textures/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("../textures/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../textures/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../textures/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("texture/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("texture/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("texture/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("Texture/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("Texture/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("Texture/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("../Texture/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../Texture/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../Texture/" + path.get_file())); - paths.push_back(p_path.get_base_dir().plus_file("../texture/" + path.get_file().get_basename() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../texture/" + path.get_file() + extension)); - paths.push_back(p_path.get_base_dir().plus_file("../texture/" + path.get_file())); - for (int i = 0; i < paths.size(); i++) { - if (dir.file_exists(paths[i])) { - found = true; - path = paths[i]; - return; - } - } - } - - /** find the texture path for the supplied fbx path inside godot - * very simple lookup for subfolders etc for a texture which may or may not be in a directory - */ - static void find_texture_path(const String &r_p_path, String &r_path, bool &r_found) { - _Directory dir; - - List<String> exts; - ImageLoader::get_recognized_extensions(&exts); - - Vector<String> split_path = r_path.get_basename().split("*"); - if (split_path.size() == 2) { - r_found = true; - return; - } - - if (dir.file_exists(r_p_path.get_base_dir() + r_path.get_file())) { - r_path = r_p_path.get_base_dir() + r_path.get_file(); - r_found = true; - return; - } - - for (int32_t i = 0; i < exts.size(); i++) { - if (r_found) { - return; - } - find_texture_path(r_p_path, dir, r_path, r_found, "." + exts[i]); - } - } - - /** - * set_texture_mapping_mode - * Helper to check the mapping mode of the texture (repeat, clamp and mirror) - */ - static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) { - ERR_FAIL_COND(texture.is_null()); - ERR_FAIL_COND(map_mode == nullptr); - // FIXME: Commented out during Vulkan port. - /* - aiTextureMapMode tex_mode = map_mode[0]; - - int32_t flags = Texture2D::FLAGS_DEFAULT; - if (tex_mode == aiTextureMapMode_Wrap) { - //Default - } else if (tex_mode == aiTextureMapMode_Clamp) { - flags = flags & ~Texture2D::FLAG_REPEAT; - } else if (tex_mode == aiTextureMapMode_Mirror) { - flags = flags | Texture2D::FLAG_MIRRORED_REPEAT; - } - texture->set_flags(flags); - */ - } - - /** - * Load or load from cache image :) - */ - static Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path) { - Map<String, Ref<Image>>::Element *match = state.path_to_image_cache.find(p_path); - - // if our cache contains this image then don't bother - if (match) { - return match->get(); - } - - Vector<String> split_path = p_path.get_basename().split("*"); - if (split_path.size() == 2) { - size_t texture_idx = split_path[1].to_int(); - ERR_FAIL_COND_V(texture_idx >= p_scene->mNumTextures, Ref<Image>()); - aiTexture *tex = p_scene->mTextures[texture_idx]; - String filename = AssimpUtils::get_raw_string_from_assimp(tex->mFilename); - filename = filename.get_file(); - print_verbose("Open Asset Import: Loading embedded texture " + filename); - if (tex->mHeight == 0) { - if (tex->CheckFormat("png")) { - ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, Ref<Image>()); - Ref<Image> img = Image::_png_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth); - ERR_FAIL_COND_V(img.is_null(), Ref<Image>()); - state.path_to_image_cache.insert(p_path, img); - return img; - } else if (tex->CheckFormat("jpg")) { - ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, Ref<Image>()); - Ref<Image> img = Image::_jpg_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth); - ERR_FAIL_COND_V(img.is_null(), Ref<Image>()); - state.path_to_image_cache.insert(p_path, img); - return img; - } else if (tex->CheckFormat("dds")) { - ERR_FAIL_COND_V_MSG(true, Ref<Image>(), "Open Asset Import: Embedded dds not implemented"); - } - } else { - Ref<Image> img; - img.instance(); - PackedByteArray arr; - uint32_t size = tex->mWidth * tex->mHeight; - arr.resize(size); - memcpy(arr.ptrw(), tex->pcData, size); - ERR_FAIL_COND_V(arr.size() % 4 != 0, Ref<Image>()); - //ARGB8888 to RGBA8888 - for (int32_t i = 0; i < arr.size() / 4; i++) { - arr.ptrw()[(4 * i) + 3] = arr[(4 * i) + 0]; - arr.ptrw()[(4 * i) + 0] = arr[(4 * i) + 1]; - arr.ptrw()[(4 * i) + 1] = arr[(4 * i) + 2]; - arr.ptrw()[(4 * i) + 2] = arr[(4 * i) + 3]; - } - img->create(tex->mWidth, tex->mHeight, true, Image::FORMAT_RGBA8, arr); - ERR_FAIL_COND_V(img.is_null(), Ref<Image>()); - state.path_to_image_cache.insert(p_path, img); - return img; - } - return Ref<Image>(); - } else { - Ref<Texture2D> texture = ResourceLoader::load(p_path); - ERR_FAIL_COND_V(texture.is_null(), Ref<Image>()); - Ref<Image> image = texture->get_data(); - ERR_FAIL_COND_V(image.is_null(), Ref<Image>()); - state.path_to_image_cache.insert(p_path, image); - return image; - } - - return Ref<Image>(); - } - - /* create texture from assimp data, if found in path */ - static bool CreateAssimpTexture( - AssimpImporter::ImportState &state, - aiString texture_path, - String &filename, - String &path, - AssimpImageData &image_state) { - filename = get_raw_string_from_assimp(texture_path); - path = state.path.get_base_dir().plus_file(filename.replace("\\", "/")); - bool found = false; - find_texture_path(state.path, path, found); - if (found) { - image_state.raw_image = AssimpUtils::load_image(state, state.assimp_scene, path); - if (image_state.raw_image.is_valid()) { - image_state.texture.instance(); - image_state.texture->create_from_image(image_state.raw_image); - // FIXME: Commented out during Vulkan port. - //image_state.texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); - return true; - } - } - - return false; - } - /** GetAssimpTexture - * Designed to retrieve textures for you - */ - static bool GetAssimpTexture( - AssimpImporter::ImportState &state, - aiMaterial *ai_material, - aiTextureType texture_type, - String &filename, - String &path, - AssimpImageData &image_state) { - aiString ai_filename = aiString(); - if (AI_SUCCESS == ai_material->GetTexture(texture_type, 0, &ai_filename, nullptr, nullptr, nullptr, nullptr, image_state.map_mode)) { - return CreateAssimpTexture(state, ai_filename, filename, path, image_state); - } - - return false; - } -}; - -#endif // IMPORT_UTILS_IMPORTER_ASSIMP_H diff --git a/modules/assimp/register_types.cpp b/modules/assimp/register_types.cpp deleted file mode 100644 index 6cb0fc982f..0000000000 --- a/modules/assimp/register_types.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************/ -/* register_types.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "register_types.h" - -#include "editor/editor_node.h" -#include "editor_scene_importer_assimp.h" - -#ifdef TOOLS_ENABLED -static void _editor_init() { - Ref<EditorSceneImporterAssimp> import_assimp; - import_assimp.instance(); - ResourceImporterScene::get_singleton()->add_importer(import_assimp); -} -#endif - -void register_assimp_types() { -#ifdef TOOLS_ENABLED - ClassDB::APIType prev_api = ClassDB::get_current_api(); - ClassDB::set_current_api(ClassDB::API_EDITOR); - - ClassDB::register_class<EditorSceneImporterAssimp>(); - - ClassDB::set_current_api(prev_api); - - EditorNode::add_init_callback(_editor_init); -#endif -} - -void unregister_assimp_types() { -} diff --git a/modules/assimp/register_types.h b/modules/assimp/register_types.h deleted file mode 100644 index f399a7acc6..0000000000 --- a/modules/assimp/register_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* register_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ASSIMP_REGISTER_TYPES_H -#define ASSIMP_REGISTER_TYPES_H - -void register_assimp_types(); -void unregister_assimp_types(); - -#endif // ASSIMP_REGISTER_TYPES_H diff --git a/thirdparty/README.md b/thirdparty/README.md index 8cb6424a1c..4ea72c8883 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -6,24 +6,6 @@ readability. Subcategories (`###` level) where needed are separated by a single empty line. -## assimp - -- Upstream: http://github.com/assimp/assimp -- Version: git (308db73d0b3c2d1870cd3e465eaa283692a4cf23, 2019) -- License: BSD-3-Clause - -Files extracted from upstream source: - -- Run `cmake .` in root folder to generate files -- `code/{CApi,Common,FBX,Material,PostProcessing}/` -- `contrib/utf8cpp/source/` -- `include/` -- `revision.h` -- `CREDITS` and `LICENSE` files -- `rm -f code/Common/ZipArchiveIOSystem.cpp include/assimp/ZipArchiveIOSystem.h - include/assimp/irrXMLWrapper.h` - - ## basis_universal - Upstream: https://github.com/BinomialLLC/basis_universal diff --git a/thirdparty/assimp/CREDITS b/thirdparty/assimp/CREDITS deleted file mode 100644 index 26e21d2f41..0000000000 --- a/thirdparty/assimp/CREDITS +++ /dev/null @@ -1,183 +0,0 @@ -=============================================================== -Open Asset Import Library (Assimp) -Developers and Contributors -=============================================================== - -The following is a non-exhaustive list of all constributors over the years. -If you think your name should be listed here, drop us a line and we'll add you. - -- Alexander Gessler, -3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Design). - -- Thomas Schulze, -X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation. - -- Kim Kulling, -Obj-, Q3BSD-, OpenGEX-Loader, Logging system, CMake-build-environment, Linux-build, Website ( Admin ), Coverity ( Admin ), Glitter ( Admin ). - -- R.Schmidt, -Linux build, eclipse support. - -- Matthias Gubisch, -Assimp.net -Visual Studio 9 support, bugfixes. - -- Mark Sibly -B3D-Loader, Assimp testing - -- Jonathan Klein -Ogre Loader, VC2010 fixes and CMake fixes. - -- Sebastian Hempel, -PyAssimp (first version) -Compile-Bugfixes for mingw, add environment for static library support in make. - -- Jonathan Pokrass -Supplied a bugfix concerning the scaling in the md3 loader. - -- Andrew Galante, -Submitted patches to make Assimp compile with GCC-4, a makefile and the xcode3 workspace. - -- Andreas Nagel -First Assimp testing & verification under Windows Vista 64 Bit. - -- Marius Schr�der -Allowed us to use many of his models for screenshots and testing. - -- Christian Schubert -Supplied various XFiles for testing purposes. - -- Tizian Wieland -Searched the web for hundreds of test models for internal use - -- John Connors -Supplied patches for linux and SCons. - -- T. R. -The GUY who performed some of the CSM mocaps. - -- Andy Maloney -Contributed fixes for the documentation and the doxygen markup - -- Zhao Lei -Contributed several bugfixes fixing memory leaks and improving float parsing - -- sueastside -Updated PyAssimp to the latest Assimp data structures and provided a script to keep the Python binding up-to-date. - -- Tobias Rittig -Collada testing with Cinema 4D - -- Brad Grantham -Improvements in OpenGL-Sample. - -- Robert Ramirez -Add group loading feature to Obj-Loader. - -- Chris Maiwald -Many bugreports, improving Assimp's portability, regular testing & feedback. - -- Stepan Hrbek -Bugreport and fix for a obj-materialloader crash. - -- David Nadlinger -D bindings, CMake install support. - -- Dario Accornero -Contributed several patches regarding Mac OS/XCode targets, bug reports. - -- Martin Walser (Samhayne) -Contributed the 'SimpleTexturedOpenGl' sample. - -- Matthias Fauconneau -Contributed a fix for the Q3-BSP loader. - -- Jørgen P. Tjernø -Contributed updated and improved xcode workspaces - -- drparallax -Contributed the /samples/SimpleAssimpViewX sample - -- Carsten Fuchs -Contributed a fix for the Normalize method in aiQuaternion. - -- dbburgess -Contributes a Android-specific build issue: log the hardware architecture for ARM. - -- alfiereinre7 -Contributes a obj-fileparser fix: missing tokens in the obj-token list. - -- Roman Kharitonov -Contributes a fix for the configure script environment. - -- Ed Diana -Contributed AssimpDelphi (/port/AssimpDelphi). - -- rdb -Contributes a bundle of fixes and improvements for the bsp-importer. - -- Mick P -For contributing the De-bone postprocessing step and filing various bug reports. - -- Rosen Diankov -Contributed patches to build assimp debian packages using cmake. - -- Mark Page -Contributed a patch to fix the VertexTriangleAdjacency postprocessing step. - -- IOhannes -Contributed the Debian build fixes ( architecture macro ). - -- gellule -Several LWO and LWS fixes (pivoting). - -- Marcel Metz -GCC/Linux fixes for the SimpleOpenGL sample. - -- Brian Miller -Bugfix for a compiler fix for iOS on arm. - -- Séverin Lemaignan -Rewrite of PyAssimp, distutils and Python3 support - -- albert-wang -Bugfixes for the collada parser - -- Ya ping Jin -Bugfixes for uv-tanget calculation. - -- Jonne Nauha -Ogre Binary format support - -- Filip Wasil, Tieto Poland Sp. z o.o. -Android JNI asset extraction support - -- Richard Steffen -Contributed ExportProperties interface -Contributed X File exporter -Contributed Step (stp) exporter - -- Thomas Iorns (mesilliac) -Initial FBX Export support - -For a more detailed list just check: https://github.com/assimp/assimp/network/members - - -======== -Patreons -======== - -Huge thanks to our Patreons! - -- migenius -- Marcus -- Cort -- elect -- Steffen - - -=================== -Commercial Sponsors -=================== - -- MyDidimo (mydidimo.com): Sponsored development of FBX Export support diff --git a/thirdparty/assimp/LICENSE b/thirdparty/assimp/LICENSE deleted file mode 100644 index 262606aff3..0000000000 --- a/thirdparty/assimp/LICENSE +++ /dev/null @@ -1,78 +0,0 @@ -Open Asset Import Library (assimp) - -Copyright (c) 2006-2016, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - -****************************************************************************** - -AN EXCEPTION applies to all files in the ./test/models-nonbsd folder. -These are 3d models for testing purposes, from various free sources -on the internet. They are - unless otherwise stated - copyright of -their respective creators, which may impose additional requirements -on the use of their work. For any of these models, see -<model-name>.source.txt for more legal information. Contact us if you -are a copyright holder and believe that we credited you inproperly or -if you don't want your files to appear in the repository. - - -****************************************************************************** - -Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors -http://code.google.com/p/poly2tri/ - -All rights reserved. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of Poly2Tri nor the names of its contributors may be - used to endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/thirdparty/assimp/code/CApi/AssimpCExport.cpp b/thirdparty/assimp/code/CApi/AssimpCExport.cpp deleted file mode 100644 index 7557edcfc6..0000000000 --- a/thirdparty/assimp/code/CApi/AssimpCExport.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file AssimpCExport.cpp -Assimp C export interface. See Exporter.cpp for some notes. -*/ - -#ifndef ASSIMP_BUILD_NO_EXPORT - -#include "CInterfaceIOWrapper.h" -#include <assimp/SceneCombiner.h> -#include "Common/ScenePrivate.h" -#include <assimp/Exporter.hpp> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API size_t aiGetExportFormatCount(void) -{ - return Exporter().GetExportFormatCount(); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index) -{ - // Note: this is valid as the index always pertains to a built-in exporter, - // for which the returned structure is guaranteed to be of static storage duration. - Exporter exporter; - const aiExportFormatDesc* orig( exporter.GetExportFormatDescription( index ) ); - if (NULL == orig) { - return NULL; - } - - aiExportFormatDesc *desc = new aiExportFormatDesc; - desc->description = new char[ strlen( orig->description ) + 1 ](); - ::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) ); - desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ](); - ::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) ); - desc->id = new char[ strlen( orig->id ) + 1 ](); - ::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) ); - - return desc; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiReleaseExportFormatDescription( const aiExportFormatDesc *desc ) { - if (NULL == desc) { - return; - } - - delete [] desc->description; - delete [] desc->fileExtension; - delete [] desc->id; - delete desc; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut) -{ - if (!pOut || !pIn) { - return; - } - - SceneCombiner::CopyScene(pOut,pIn,true); - ScenePriv(*pOut)->mIsCopy = true; -} - - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn) -{ - // note: aiReleaseImport() is also able to delete scene copies, but in addition - // it also handles scenes with import metadata. - delete pIn; -} - - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing ) -{ - return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing); -} - - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing ) -{ - Exporter exp; - - if (pIO) { - exp.SetIOHandler(new CIOSystemWrapper(pIO)); - } - return exp.Export(pScene,pFormatId,pFileName,pPreprocessing); -} - - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing ) -{ - Exporter exp; - if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) { - return NULL; - } - const aiExportDataBlob* blob = exp.GetOrphanedBlob(); - ai_assert(blob); - - return blob; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData ) -{ - delete pData; -} - -#endif // !ASSIMP_BUILD_NO_EXPORT diff --git a/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp deleted file mode 100644 index 5a3a49565a..0000000000 --- a/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file aiFileIO -> IOSystem wrapper*/ - -#include "CInterfaceIOWrapper.h" - -namespace Assimp { - -CIOStreamWrapper::~CIOStreamWrapper(void) -{ - /* Various places depend on this destructor to close the file */ - if (mFile) { - mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile); - mFile = nullptr; - } -} - -// ................................................................... -size_t CIOStreamWrapper::Read(void* pvBuffer, - size_t pSize, - size_t pCount -){ - // need to typecast here as C has no void* - return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount); -} - -// ................................................................... -size_t CIOStreamWrapper::Write(const void* pvBuffer, - size_t pSize, - size_t pCount -){ - // need to typecast here as C has no void* - return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount); -} - -// ................................................................... -aiReturn CIOStreamWrapper::Seek(size_t pOffset, - aiOrigin pOrigin -){ - return mFile->SeekProc(mFile,pOffset,pOrigin); -} - -// ................................................................... -size_t CIOStreamWrapper::Tell(void) const { - return mFile->TellProc(mFile); -} - -// ................................................................... -size_t CIOStreamWrapper::FileSize() const { - return mFile->FileSizeProc(mFile); -} - -// ................................................................... -void CIOStreamWrapper::Flush () { - return mFile->FlushProc(mFile); -} - -// ------------------------------------------------------------------------------------------------ -// Custom IOStream implementation for the C-API -bool CIOSystemWrapper::Exists( const char* pFile) const { - aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb"); - if (p){ - mFileSystem->CloseProc(mFileSystem,p); - return true; - } - return false; -} - -// ................................................................... -char CIOSystemWrapper::getOsSeparator() const { -#ifndef _WIN32 - return '/'; -#else - return '\\'; -#endif -} - -// ................................................................... -IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) { - aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode); - if (!p) { - return NULL; - } - return new CIOStreamWrapper(p, this); -} - -// ................................................................... -void CIOSystemWrapper::Close( IOStream* pFile) { - if (!pFile) { - return; - } - delete pFile; -} - -} diff --git a/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h deleted file mode 100644 index 2162320302..0000000000 --- a/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h +++ /dev/null @@ -1,99 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file aiFileIO -> IOSystem wrapper*/ - -#ifndef AI_CIOSYSTEM_H_INCLUDED -#define AI_CIOSYSTEM_H_INCLUDED - -#include <assimp/cfileio.h> -#include <assimp/IOStream.hpp> -#include <assimp/IOSystem.hpp> - -namespace Assimp { - -class CIOSystemWrapper; - -// ------------------------------------------------------------------------------------------------ -// Custom IOStream implementation for the C-API -class CIOStreamWrapper : public IOStream -{ -public: - explicit CIOStreamWrapper(aiFile* pFile, CIOSystemWrapper* io) - : mFile(pFile), - mIO(io) - {} - ~CIOStreamWrapper(void); - - size_t Read(void* pvBuffer, size_t pSize, size_t pCount); - size_t Write(const void* pvBuffer, size_t pSize, size_t pCount); - aiReturn Seek(size_t pOffset, aiOrigin pOrigin); - size_t Tell(void) const; - size_t FileSize() const; - void Flush(); - -private: - aiFile* mFile; - CIOSystemWrapper* mIO; -}; - -class CIOSystemWrapper : public IOSystem -{ - friend class CIOStreamWrapper; -public: - explicit CIOSystemWrapper(aiFileIO* pFile) - : mFileSystem(pFile) - {} - - bool Exists( const char* pFile) const; - char getOsSeparator() const; - IOStream* Open(const char* pFile,const char* pMode = "rb"); - void Close( IOStream* pFile); -private: - aiFileIO* mFileSystem; -}; - -} - -#endif - diff --git a/thirdparty/assimp/code/Common/Assimp.cpp b/thirdparty/assimp/code/Common/Assimp.cpp deleted file mode 100644 index 178b2c01d0..0000000000 --- a/thirdparty/assimp/code/Common/Assimp.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file Assimp.cpp - * @brief Implementation of the Plain-C API - */ - -#include <assimp/cimport.h> -#include <assimp/LogStream.hpp> -#include <assimp/DefaultLogger.hpp> -#include <assimp/Importer.hpp> -#include <assimp/importerdesc.h> -#include <assimp/scene.h> -#include <assimp/GenericProperty.h> -#include <assimp/Exceptional.h> -#include <assimp/BaseImporter.h> - -#include "CApi/CInterfaceIOWrapper.h" -#include "Importer.h" -#include "ScenePrivate.h" - -#include <list> - -// ------------------------------------------------------------------------------------------------ -#ifndef ASSIMP_BUILD_SINGLETHREADED -# include <thread> -# include <mutex> -#endif -// ------------------------------------------------------------------------------------------------ -using namespace Assimp; - -namespace Assimp { - // underlying structure for aiPropertyStore - typedef BatchLoader::PropertyMap PropertyMap; - - /** Stores the LogStream objects for all active C log streams */ - struct mpred { - bool operator () (const aiLogStream& s0, const aiLogStream& s1) const { - return s0.callback<s1.callback&&s0.user<s1.user; - } - }; - typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap; - - /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */ - typedef std::list<Assimp::LogStream*> PredefLogStreamMap; - - /** Local storage of all active log streams */ - static LogStreamMap gActiveLogStreams; - - /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */ - static PredefLogStreamMap gPredefinedStreams; - - /** Error message of the last failed import process */ - static std::string gLastErrorString; - - /** Verbose logging active or not? */ - static aiBool gVerboseLogging = false; - - /** will return all registered importers. */ - void GetImporterInstanceList(std::vector< BaseImporter* >& out); - - /** will delete all registered importers. */ - void DeleteImporterInstanceList(std::vector< BaseImporter* >& out); -} // namespace assimp - - -#ifndef ASSIMP_BUILD_SINGLETHREADED -/** Global mutex to manage the access to the log-stream map */ -static std::mutex gLogStreamMutex; -#endif - -// ------------------------------------------------------------------------------------------------ -// Custom LogStream implementation for the C-API -class LogToCallbackRedirector : public LogStream { -public: - explicit LogToCallbackRedirector(const aiLogStream& s) - : stream (s) { - ai_assert(NULL != s.callback); - } - - ~LogToCallbackRedirector() { -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(gLogStreamMutex); -#endif - // (HACK) Check whether the 'stream.user' pointer points to a - // custom LogStream allocated by #aiGetPredefinedLogStream. - // In this case, we need to delete it, too. Of course, this - // might cause strange problems, but the chance is quite low. - - PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(), - gPredefinedStreams.end(), (Assimp::LogStream*)stream.user); - - if (it != gPredefinedStreams.end()) { - delete *it; - gPredefinedStreams.erase(it); - } - } - - /** @copydoc LogStream::write */ - void write(const char* message) { - stream.callback(message,stream.user); - } - -private: - aiLogStream stream; -}; - -// ------------------------------------------------------------------------------------------------ -void ReportSceneNotFoundError() { - ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. " - "The C-API does not accept scenes produced by the C++ API and vice versa"); - - ai_assert(false); -} - -// ------------------------------------------------------------------------------------------------ -// Reads the given file and returns its content. -const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) { - return aiImportFileEx(pFile,pFlags,NULL); -} - -// ------------------------------------------------------------------------------------------------ -const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) { - return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL); -} - -// ------------------------------------------------------------------------------------------------ -const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags, - aiFileIO* pFS, const aiPropertyStore* props) { - ai_assert(NULL != pFile); - - const aiScene* scene = NULL; - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // create an Importer for this file - Assimp::Importer* imp = new Assimp::Importer(); - - // copy properties - if(props) { - const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props); - ImporterPimpl* pimpl = imp->Pimpl(); - pimpl->mIntProperties = pp->ints; - pimpl->mFloatProperties = pp->floats; - pimpl->mStringProperties = pp->strings; - pimpl->mMatrixProperties = pp->matrices; - } - // setup a custom IO system if necessary - if (pFS) { - imp->SetIOHandler( new CIOSystemWrapper (pFS) ); - } - - // and have it read the file - scene = imp->ReadFile( pFile, pFlags); - - // if succeeded, store the importer in the scene and keep it alive - if( scene) { - ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) ); - priv->mOrigImporter = imp; - } else { - // if failed, extract error code and destroy the import - gLastErrorString = imp->GetErrorString(); - delete imp; - } - - // return imported data. If the import failed the pointer is NULL anyways - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - - return scene; -} - -// ------------------------------------------------------------------------------------------------ -const aiScene* aiImportFileFromMemory( - const char* pBuffer, - unsigned int pLength, - unsigned int pFlags, - const char* pHint) -{ - return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL); -} - -// ------------------------------------------------------------------------------------------------ -const aiScene* aiImportFileFromMemoryWithProperties( - const char* pBuffer, - unsigned int pLength, - unsigned int pFlags, - const char* pHint, - const aiPropertyStore* props) -{ - ai_assert( NULL != pBuffer ); - ai_assert( 0 != pLength ); - - const aiScene* scene = NULL; - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // create an Importer for this file - Assimp::Importer* imp = new Assimp::Importer(); - - // copy properties - if(props) { - const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props); - ImporterPimpl* pimpl = imp->Pimpl(); - pimpl->mIntProperties = pp->ints; - pimpl->mFloatProperties = pp->floats; - pimpl->mStringProperties = pp->strings; - pimpl->mMatrixProperties = pp->matrices; - } - - // and have it read the file from the memory buffer - scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint); - - // if succeeded, store the importer in the scene and keep it alive - if( scene) { - ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) ); - priv->mOrigImporter = imp; - } - else { - // if failed, extract error code and destroy the import - gLastErrorString = imp->GetErrorString(); - delete imp; - } - // return imported data. If the import failed the pointer is NULL anyways - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return scene; -} - -// ------------------------------------------------------------------------------------------------ -// Releases all resources associated with the given import process. -void aiReleaseImport( const aiScene* pScene) -{ - if (!pScene) { - return; - } - - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // find the importer associated with this data - const ScenePrivateData* priv = ScenePriv(pScene); - if( !priv || !priv->mOrigImporter) { - delete pScene; - } - else { - // deleting the Importer also deletes the scene - // Note: the reason that this is not written as 'delete priv->mOrigImporter' - // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339) - Importer* importer = priv->mOrigImporter; - delete importer; - } - - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene, - unsigned int pFlags) -{ - const aiScene* sc = NULL; - - - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // find the importer associated with this data - const ScenePrivateData* priv = ScenePriv(pScene); - if( !priv || !priv->mOrigImporter) { - ReportSceneNotFoundError(); - return NULL; - } - - sc = priv->mOrigImporter->ApplyPostProcessing(pFlags); - - if (!sc) { - aiReleaseImport(pScene); - return NULL; - } - - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return sc; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing( const aiScene *scene, - BaseProcess* process, - bool requestValidation ) { - const aiScene* sc( NULL ); - - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // find the importer associated with this data - const ScenePrivateData* priv = ScenePriv( scene ); - if ( NULL == priv || NULL == priv->mOrigImporter ) { - ReportSceneNotFoundError(); - return NULL; - } - - sc = priv->mOrigImporter->ApplyCustomizedPostProcessing( process, requestValidation ); - - if ( !sc ) { - aiReleaseImport( scene ); - return NULL; - } - - ASSIMP_END_EXCEPTION_REGION( const aiScene* ); - - return sc; -} - -// ------------------------------------------------------------------------------------------------ -void CallbackToLogRedirector (const char* msg, char* dt) -{ - ai_assert( NULL != msg ); - ai_assert( NULL != dt ); - LogStream* s = (LogStream*)dt; - - s->write(msg); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file) -{ - aiLogStream sout; - - ASSIMP_BEGIN_EXCEPTION_REGION(); - LogStream* stream = LogStream::createDefaultStream(pStream,file); - if (!stream) { - sout.callback = NULL; - sout.user = NULL; - } - else { - sout.callback = &CallbackToLogRedirector; - sout.user = (char*)stream; - } - gPredefinedStreams.push_back(stream); - ASSIMP_END_EXCEPTION_REGION(aiLogStream); - return sout; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiAttachLogStream( const aiLogStream* stream ) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(gLogStreamMutex); -#endif - - LogStream* lg = new LogToCallbackRedirector(*stream); - gActiveLogStreams[*stream] = lg; - - if (DefaultLogger::isNullLogger()) { - DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL)); - } - DefaultLogger::get()->attachStream(lg); - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(gLogStreamMutex); -#endif - // find the log-stream associated with this data - LogStreamMap::iterator it = gActiveLogStreams.find( *stream); - // it should be there... else the user is playing fools with us - if( it == gActiveLogStreams.end()) { - return AI_FAILURE; - } - DefaultLogger::get()->detatchStream( it->second ); - delete it->second; - - gActiveLogStreams.erase( it); - - if (gActiveLogStreams.empty()) { - DefaultLogger::kill(); - } - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiDetachAllLogStreams(void) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(gLogStreamMutex); -#endif - Logger *logger( DefaultLogger::get() ); - if ( NULL == logger ) { - return; - } - - for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) { - logger->detatchStream( it->second ); - delete it->second; - } - gActiveLogStreams.clear(); - DefaultLogger::kill(); - - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiEnableVerboseLogging(aiBool d) -{ - if (!DefaultLogger::isNullLogger()) { - DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL)); - } - gVerboseLogging = d; -} - -// ------------------------------------------------------------------------------------------------ -// Returns the error text of the last failed import process. -const char* aiGetErrorString() -{ - return gLastErrorString.c_str(); -} - -// ----------------------------------------------------------------------------------------------- -// Return the description of a importer given its index -const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex) -{ - return Importer().GetImporterInfo(pIndex); -} - -// ----------------------------------------------------------------------------------------------- -// Return the number of importers -size_t aiGetImportFormatCount(void) -{ - return Importer().GetImporterCount(); -} - -// ------------------------------------------------------------------------------------------------ -// Returns the error text of the last failed import process. -aiBool aiIsExtensionSupported(const char* szExtension) -{ - ai_assert(NULL != szExtension); - aiBool candoit=AI_FALSE; - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // FIXME: no need to create a temporary Importer instance just for that .. - Assimp::Importer tmp; - candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE; - - ASSIMP_END_EXCEPTION_REGION(aiBool); - return candoit; -} - -// ------------------------------------------------------------------------------------------------ -// Get a list of all file extensions supported by ASSIMP -void aiGetExtensionList(aiString* szOut) -{ - ai_assert(NULL != szOut); - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // FIXME: no need to create a temporary Importer instance just for that .. - Assimp::Importer tmp; - tmp.GetExtensionList(*szOut); - - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Get the memory requirements for a particular import. -void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn, - C_STRUCT aiMemoryInfo* in) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // find the importer associated with this data - const ScenePrivateData* priv = ScenePriv(pIn); - if( !priv || !priv->mOrigImporter) { - ReportSceneNotFoundError(); - return; - } - - return priv->mOrigImporter->GetMemoryRequirements(*in); - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void) -{ - return reinterpret_cast<aiPropertyStore*>( new PropertyMap() ); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p) -{ - delete reinterpret_cast<PropertyMap*>(p); -} - -// ------------------------------------------------------------------------------------------------ -// Importer::SetPropertyInteger -ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); - SetGenericProperty<int>(pp->ints,szName,value); - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Importer::SetPropertyFloat -ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, ai_real value) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); - SetGenericProperty<ai_real>(pp->floats,szName,value); - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Importer::SetPropertyString -ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName, - const C_STRUCT aiString* st) -{ - if (!st) { - return; - } - ASSIMP_BEGIN_EXCEPTION_REGION(); - PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); - SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str())); - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Importer::SetPropertyMatrix -ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName, - const C_STRUCT aiMatrix4x4* mat) -{ - if (!mat) { - return; - } - ASSIMP_BEGIN_EXCEPTION_REGION(); - PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); - SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat); - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Rotation matrix to quaternion -ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat) -{ - ai_assert( NULL != quat ); - ai_assert( NULL != mat ); - *quat = aiQuaternion(*mat); -} - -// ------------------------------------------------------------------------------------------------ -// Matrix decomposition -ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling, - aiQuaternion* rotation, - aiVector3D* position) -{ - ai_assert( NULL != rotation ); - ai_assert( NULL != position ); - ai_assert( NULL != scaling ); - ai_assert( NULL != mat ); - mat->Decompose(*scaling,*rotation,*position); -} - -// ------------------------------------------------------------------------------------------------ -// Matrix transpose -ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat) -{ - ai_assert(NULL != mat); - mat->Transpose(); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat) -{ - ai_assert(NULL != mat); - mat->Transpose(); -} - -// ------------------------------------------------------------------------------------------------ -// Vector transformation -ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec, - const aiMatrix3x3* mat) -{ - ai_assert( NULL != mat ); - ai_assert( NULL != vec); - *vec *= (*mat); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec, - const aiMatrix4x4* mat) -{ - ai_assert( NULL != mat ); - ai_assert( NULL != vec ); - - *vec *= (*mat); -} - -// ------------------------------------------------------------------------------------------------ -// Matrix multiplication -ASSIMP_API void aiMultiplyMatrix4( - aiMatrix4x4* dst, - const aiMatrix4x4* src) -{ - ai_assert( NULL != dst ); - ai_assert( NULL != src ); - *dst = (*dst) * (*src); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiMultiplyMatrix3( - aiMatrix3x3* dst, - const aiMatrix3x3* src) -{ - ai_assert( NULL != dst ); - ai_assert( NULL != src ); - *dst = (*dst) * (*src); -} - -// ------------------------------------------------------------------------------------------------ -// Matrix identity -ASSIMP_API void aiIdentityMatrix3( - aiMatrix3x3* mat) -{ - ai_assert(NULL != mat); - *mat = aiMatrix3x3(); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API void aiIdentityMatrix4( - aiMatrix4x4* mat) -{ - ai_assert(NULL != mat); - *mat = aiMatrix4x4(); -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) { - if( NULL == extension ) { - return NULL; - } - const aiImporterDesc *desc( NULL ); - std::vector< BaseImporter* > out; - GetImporterInstanceList( out ); - for( size_t i = 0; i < out.size(); ++i ) { - if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) { - desc = out[ i ]->GetInfo(); - break; - } - } - - DeleteImporterInstanceList(out); - - return desc; -} - -// ------------------------------------------------------------------------------------------------ diff --git a/thirdparty/assimp/code/Common/BaseImporter.cpp b/thirdparty/assimp/code/Common/BaseImporter.cpp deleted file mode 100644 index 5c1e605549..0000000000 --- a/thirdparty/assimp/code/Common/BaseImporter.cpp +++ /dev/null @@ -1,656 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file BaseImporter.cpp - * @brief Implementation of BaseImporter - */ - -#include <assimp/BaseImporter.h> -#include <assimp/ParsingUtils.h> -#include "FileSystemFilter.h" -#include "Importer.h" -#include <assimp/ByteSwapper.h> -#include <assimp/scene.h> -#include <assimp/Importer.hpp> -#include <assimp/postprocess.h> -#include <assimp/importerdesc.h> - -#include <ios> -#include <list> -#include <memory> -#include <sstream> -#include <cctype> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -BaseImporter::BaseImporter() AI_NO_EXCEPT -: m_progress() { - /** - * Assimp Importer - * unit conversions available - * if you need another measurment unit add it below. - * it's currently defined in assimp that we prefer meters. - * - * NOTE: Initialised here rather than in the header file - * to workaround a VS2013 bug with brace initialisers - * */ - importerUnits[ImporterUnits::M] = 1.0; - importerUnits[ImporterUnits::CM] = 0.01; - importerUnits[ImporterUnits::MM] = 0.001; - importerUnits[ImporterUnits::INCHES] = 0.0254; - importerUnits[ImporterUnits::FEET] = 0.3048; -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -BaseImporter::~BaseImporter() { - // nothing to do here -} - -void BaseImporter::UpdateImporterScale( Importer* pImp ) -{ - ai_assert(pImp != nullptr); - ai_assert(importerScale != 0.0); - ai_assert(fileScale != 0.0); - - double activeScale = importerScale * fileScale; - - // Set active scaling - pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) ); - - ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale ); -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file and returns the imported data. -aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) { - - - m_progress = pImp->GetProgressHandler(); - if (nullptr == m_progress) { - return nullptr; - } - - ai_assert(m_progress); - - // Gather configuration properties for this run - SetupProperties( pImp ); - - // Construct a file system filter to improve our success ratio at reading external files - FileSystemFilter filter(pFile,pIOHandler); - - // create a scene object to hold the data - std::unique_ptr<aiScene> sc(new aiScene()); - - // dispatch importing - try - { - InternReadFile( pFile, sc.get(), &filter); - - // Calculate import scale hook - required because pImp not available anywhere else - // passes scale into ScaleProcess - UpdateImporterScale(pImp); - - - } catch( const std::exception& err ) { - // extract error description - m_ErrorText = err.what(); - ASSIMP_LOG_ERROR(m_ErrorText); - return nullptr; - } - - // return what we gathered from the import. - return sc.release(); -} - -// ------------------------------------------------------------------------------------------------ -void BaseImporter::SetupProperties(const Importer* pImp) -{ - // the default implementation does nothing -} - -// ------------------------------------------------------------------------------------------------ -void BaseImporter::GetExtensionList(std::set<std::string>& extensions) { - const aiImporterDesc* desc = GetInfo(); - ai_assert(desc != nullptr); - - const char* ext = desc->mFileExtensions; - ai_assert(ext != nullptr ); - - const char* last = ext; - do { - if (!*ext || *ext == ' ') { - extensions.insert(std::string(last,ext-last)); - ai_assert(ext-last > 0); - last = ext; - while(*last == ' ') { - ++last; - } - } - } - while(*ext++); -} - -// ------------------------------------------------------------------------------------------------ -/*static*/ bool BaseImporter::SearchFileHeaderForToken( IOSystem* pIOHandler, - const std::string& pFile, - const char** tokens, - unsigned int numTokens, - unsigned int searchBytes /* = 200 */, - bool tokensSol /* false */, - bool noAlphaBeforeTokens /* false */) -{ - ai_assert( nullptr != tokens ); - ai_assert( 0 != numTokens ); - ai_assert( 0 != searchBytes); - - if ( nullptr == pIOHandler ) { - return false; - } - - std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile)); - if (pStream.get() ) { - // read 200 characters from the file - std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]); - char *buffer( _buffer.get() ); - const size_t read( pStream->Read(buffer,1,searchBytes) ); - if( 0 == read ) { - return false; - } - - for( size_t i = 0; i < read; ++i ) { - buffer[ i ] = static_cast<char>( ::tolower( buffer[ i ] ) ); - } - - // It is not a proper handling of unicode files here ... - // ehm ... but it works in most cases. - char* cur = buffer,*cur2 = buffer,*end = &buffer[read]; - while (cur != end) { - if( *cur ) { - *cur2++ = *cur; - } - ++cur; - } - *cur2 = '\0'; - - std::string token; - for (unsigned int i = 0; i < numTokens; ++i ) { - ai_assert( nullptr != tokens[i] ); - const size_t len( strlen( tokens[ i ] ) ); - token.clear(); - const char *ptr( tokens[ i ] ); - for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) { - token.push_back( static_cast<char>( tolower( *ptr ) ) ); - ++ptr; - } - const char* r = strstr( buffer, token.c_str() ); - if( !r ) { - continue; - } - // We need to make sure that we didn't accidentially identify the end of another token as our token, - // e.g. in a previous version the "gltf " present in some gltf files was detected as "f " - if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) { - continue; - } - // We got a match, either we don't care where it is, or it happens to - // be in the beginning of the file / line - if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') { - ASSIMP_LOG_DEBUG_F( "Found positive match for header keyword: ", tokens[i] ); - return true; - } - } - } - - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Simple check for file extension -/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile, - const char* ext0, - const char* ext1, - const char* ext2) -{ - std::string::size_type pos = pFile.find_last_of('.'); - - // no file extension - can't read - if( pos == std::string::npos) - return false; - - const char* ext_real = & pFile[ pos+1 ]; - if( !ASSIMP_stricmp(ext_real,ext0) ) - return true; - - // check for other, optional, file extensions - if (ext1 && !ASSIMP_stricmp(ext_real,ext1)) - return true; - - if (ext2 && !ASSIMP_stricmp(ext_real,ext2)) - return true; - - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Get file extension from path -std::string BaseImporter::GetExtension( const std::string& file ) { - std::string::size_type pos = file.find_last_of('.'); - - // no file extension at all - if (pos == std::string::npos) { - return ""; - } - - - // thanks to Andy Maloney for the hint - std::string ret = file.substr( pos + 1 ); - std::transform( ret.begin(), ret.end(), ret.begin(), ToLower<char>); - - return ret; -} - -// ------------------------------------------------------------------------------------------------ -// Check for magic bytes at the beginning of the file. -/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, - const void* _magic, unsigned int num, unsigned int offset, unsigned int size) -{ - ai_assert( size <= 16 ); - ai_assert( _magic ); - - if (!pIOHandler) { - return false; - } - union { - const char* magic; - const uint16_t* magic_u16; - const uint32_t* magic_u32; - }; - magic = reinterpret_cast<const char*>(_magic); - std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile)); - if (pStream.get() ) { - - // skip to offset - pStream->Seek(offset,aiOrigin_SET); - - // read 'size' characters from the file - union { - char data[16]; - uint16_t data_u16[8]; - uint32_t data_u32[4]; - }; - if(size != pStream->Read(data,1,size)) { - return false; - } - - for (unsigned int i = 0; i < num; ++i) { - // also check against big endian versions of tokens with size 2,4 - // that's just for convenience, the chance that we cause conflicts - // is quite low and it can save some lines and prevent nasty bugs - if (2 == size) { - uint16_t rev = *magic_u16; - ByteSwap::Swap(&rev); - if (data_u16[0] == *magic_u16 || data_u16[0] == rev) { - return true; - } - } - else if (4 == size) { - uint32_t rev = *magic_u32; - ByteSwap::Swap(&rev); - if (data_u32[0] == *magic_u32 || data_u32[0] == rev) { - return true; - } - } - else { - // any length ... just compare - if(!memcmp(magic,data,size)) { - return true; - } - } - magic += size; - } - } - return false; -} - -#ifdef ASSIMP_USE_HUNTER -# include <utf8/utf8.h> -#else -# include "../contrib/utf8cpp/source/utf8.h" -#endif - -// ------------------------------------------------------------------------------------------------ -// Convert to UTF8 data -void BaseImporter::ConvertToUTF8(std::vector<char>& data) -{ - //ConversionResult result; - if(data.size() < 8) { - throw DeadlyImportError("File is too small"); - } - - // UTF 8 with BOM - if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) { - ASSIMP_LOG_DEBUG("Found UTF-8 BOM ..."); - - std::copy(data.begin()+3,data.end(),data.begin()); - data.resize(data.size()-3); - return; - } - - - // UTF 32 BE with BOM - if(*((uint32_t*)&data.front()) == 0xFFFE0000) { - - // swap the endianness .. - for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) { - AI_SWAP4P(p); - } - } - - // UTF 32 LE with BOM - if(*((uint32_t*)&data.front()) == 0x0000FFFE) { - ASSIMP_LOG_DEBUG("Found UTF-32 BOM ..."); - - std::vector<char> output; - int *ptr = (int*)&data[ 0 ]; - int *end = ptr + ( data.size() / sizeof(int) ) +1; - utf8::utf32to8( ptr, end, back_inserter(output)); - return; - } - - // UTF 16 BE with BOM - if(*((uint16_t*)&data.front()) == 0xFFFE) { - - // swap the endianness .. - for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) { - ByteSwap::Swap2(p); - } - } - - // UTF 16 LE with BOM - if(*((uint16_t*)&data.front()) == 0xFEFF) { - ASSIMP_LOG_DEBUG("Found UTF-16 BOM ..."); - - std::vector<unsigned char> output; - utf8::utf16to8(data.begin(), data.end(), back_inserter(output)); - return; - } -} - -// ------------------------------------------------------------------------------------------------ -// Convert to UTF8 data to ISO-8859-1 -void BaseImporter::ConvertUTF8toISO8859_1(std::string& data) -{ - size_t size = data.size(); - size_t i = 0, j = 0; - - while(i < size) { - if ((unsigned char) data[i] < (size_t) 0x80) { - data[j] = data[i]; - } else if(i < size - 1) { - if((unsigned char) data[i] == 0xC2) { - data[j] = data[++i]; - } else if((unsigned char) data[i] == 0xC3) { - data[j] = ((unsigned char) data[++i] + 0x40); - } else { - std::stringstream stream; - stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1."; - ASSIMP_LOG_ERROR( stream.str() ); - - data[j++] = data[i++]; - data[j] = data[i]; - } - } else { - ASSIMP_LOG_ERROR("UTF8 code but only one character remaining"); - - data[j] = data[i]; - } - - i++; j++; - } - - data.resize(j); -} - -// ------------------------------------------------------------------------------------------------ -void BaseImporter::TextFileToBuffer(IOStream* stream, - std::vector<char>& data, - TextFileMode mode) -{ - ai_assert(nullptr != stream); - - const size_t fileSize = stream->FileSize(); - if (mode == FORBID_EMPTY) { - if(!fileSize) { - throw DeadlyImportError("File is empty"); - } - } - - data.reserve(fileSize+1); - data.resize(fileSize); - if(fileSize > 0) { - if(fileSize != stream->Read( &data[0], 1, fileSize)) { - throw DeadlyImportError("File read error"); - } - - ConvertToUTF8(data); - } - - // append a binary zero to simplify string parsing - data.push_back(0); -} - -// ------------------------------------------------------------------------------------------------ -namespace Assimp { - // Represents an import request - struct LoadRequest { - LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id) - : file(_file) - , flags(_flags) - , refCnt(1) - , scene(NULL) - , loaded(false) - , id(_id) { - if ( _map ) { - map = *_map; - } - } - - bool operator== ( const std::string& f ) const { - return file == f; - } - - const std::string file; - unsigned int flags; - unsigned int refCnt; - aiScene *scene; - bool loaded; - BatchLoader::PropertyMap map; - unsigned int id; - }; -} - -// ------------------------------------------------------------------------------------------------ -// BatchLoader::pimpl data structure -struct Assimp::BatchData { - BatchData( IOSystem* pIO, bool validate ) - : pIOSystem( pIO ) - , pImporter( nullptr ) - , next_id(0xffff) - , validate( validate ) { - ai_assert( nullptr != pIO ); - - pImporter = new Importer(); - pImporter->SetIOHandler( pIO ); - } - - ~BatchData() { - pImporter->SetIOHandler( nullptr ); /* get pointer back into our possession */ - delete pImporter; - } - - // IO system to be used for all imports - IOSystem* pIOSystem; - - // Importer used to load all meshes - Importer* pImporter; - - // List of all imports - std::list<LoadRequest> requests; - - // Base path - std::string pathBase; - - // Id for next item - unsigned int next_id; - - // Validation enabled state - bool validate; -}; - -typedef std::list<LoadRequest>::iterator LoadReqIt; - -// ------------------------------------------------------------------------------------------------ -BatchLoader::BatchLoader(IOSystem* pIO, bool validate ) { - ai_assert(nullptr != pIO); - - m_data = new BatchData( pIO, validate ); -} - -// ------------------------------------------------------------------------------------------------ -BatchLoader::~BatchLoader() -{ - // delete all scenes what have not been polled by the user - for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) { - delete (*it).scene; - } - delete m_data; -} - -// ------------------------------------------------------------------------------------------------ -void BatchLoader::setValidation( bool enabled ) { - m_data->validate = enabled; -} - -// ------------------------------------------------------------------------------------------------ -bool BatchLoader::getValidation() const { - return m_data->validate; -} - -// ------------------------------------------------------------------------------------------------ -unsigned int BatchLoader::AddLoadRequest(const std::string& file, - unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/) -{ - ai_assert(!file.empty()); - - // check whether we have this loading request already - for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) { - // Call IOSystem's path comparison function here - if ( m_data->pIOSystem->ComparePaths((*it).file,file)) { - if (map) { - if ( !( ( *it ).map == *map ) ) { - continue; - } - } - else if ( !( *it ).map.empty() ) { - continue; - } - - (*it).refCnt++; - return (*it).id; - } - } - - // no, we don't have it. So add it to the queue ... - m_data->requests.push_back(LoadRequest(file,steps,map, m_data->next_id)); - return m_data->next_id++; -} - -// ------------------------------------------------------------------------------------------------ -aiScene* BatchLoader::GetImport( unsigned int which ) -{ - for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) { - if ((*it).id == which && (*it).loaded) { - aiScene* sc = (*it).scene; - if (!(--(*it).refCnt)) { - m_data->requests.erase(it); - } - return sc; - } - } - return nullptr; -} - - - -// ------------------------------------------------------------------------------------------------ -void BatchLoader::LoadAll() -{ - // no threaded implementation for the moment - for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) { - // force validation in debug builds - unsigned int pp = (*it).flags; - if ( m_data->validate ) { - pp |= aiProcess_ValidateDataStructure; - } - - // setup config properties if necessary - ImporterPimpl* pimpl = m_data->pImporter->Pimpl(); - pimpl->mFloatProperties = (*it).map.floats; - pimpl->mIntProperties = (*it).map.ints; - pimpl->mStringProperties = (*it).map.strings; - pimpl->mMatrixProperties = (*it).map.matrices; - - if (!DefaultLogger::isNullLogger()) - { - ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%"); - ASSIMP_LOG_INFO_F("File: ", (*it).file); - } - m_data->pImporter->ReadFile((*it).file,pp); - (*it).scene = m_data->pImporter->GetOrphanedScene(); - (*it).loaded = true; - - ASSIMP_LOG_INFO("%%% END EXTERNAL FILE %%%"); - } -} diff --git a/thirdparty/assimp/code/Common/BaseProcess.cpp b/thirdparty/assimp/code/Common/BaseProcess.cpp deleted file mode 100644 index e247be418d..0000000000 --- a/thirdparty/assimp/code/Common/BaseProcess.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of BaseProcess */ - -#include <assimp/BaseImporter.h> -#include "BaseProcess.h" -#include <assimp/DefaultLogger.hpp> -#include <assimp/scene.h> -#include "Importer.h" - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -BaseProcess::BaseProcess() AI_NO_EXCEPT -: shared() -, progress() -{ -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -BaseProcess::~BaseProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -void BaseProcess::ExecuteOnScene( Importer* pImp) -{ - ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene); - - progress = pImp->GetProgressHandler(); - ai_assert(progress); - - SetupProperties( pImp ); - - // catch exceptions thrown inside the PostProcess-Step - try - { - Execute(pImp->Pimpl()->mScene); - - } catch( const std::exception& err ) { - - // extract error description - pImp->Pimpl()->mErrorString = err.what(); - ASSIMP_LOG_ERROR(pImp->Pimpl()->mErrorString); - - // and kill the partially imported data - delete pImp->Pimpl()->mScene; - pImp->Pimpl()->mScene = nullptr; - } -} - -// ------------------------------------------------------------------------------------------------ -void BaseProcess::SetupProperties(const Importer* /*pImp*/) -{ - // the default implementation does nothing -} - -// ------------------------------------------------------------------------------------------------ -bool BaseProcess::RequireVerboseFormat() const -{ - return true; -} - diff --git a/thirdparty/assimp/code/Common/BaseProcess.h b/thirdparty/assimp/code/Common/BaseProcess.h deleted file mode 100644 index 4d5c7a76be..0000000000 --- a/thirdparty/assimp/code/Common/BaseProcess.h +++ /dev/null @@ -1,290 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Base class of all import post processing steps */ -#ifndef INCLUDED_AI_BASEPROCESS_H -#define INCLUDED_AI_BASEPROCESS_H - -#include <map> -#include <assimp/GenericProperty.h> - -struct aiScene; - -namespace Assimp { - -class Importer; - -// --------------------------------------------------------------------------- -/** Helper class to allow post-processing steps to interact with each other. - * - * The class maintains a simple property list that can be used by pp-steps - * to provide additional information to other steps. This is primarily - * intended for cross-step optimizations. - */ -class SharedPostProcessInfo -{ -public: - - struct Base - { - virtual ~Base() - {} - }; - - //! Represents data that is allocated on the heap, thus needs to be deleted - template <typename T> - struct THeapData : public Base - { - explicit THeapData(T* in) - : data (in) - {} - - ~THeapData() - { - delete data; - } - T* data; - }; - - //! Represents static, by-value data not allocated on the heap - template <typename T> - struct TStaticData : public Base - { - explicit TStaticData(T in) - : data (in) - {} - - ~TStaticData() - {} - - T data; - }; - - // some typedefs for cleaner code - typedef unsigned int KeyType; - typedef std::map<KeyType, Base*> PropertyMap; - -public: - - //! Destructor - ~SharedPostProcessInfo() - { - Clean(); - } - - //! Remove all stored properties from the table - void Clean() - { - // invoke the virtual destructor for all stored properties - for (PropertyMap::iterator it = pmap.begin(), end = pmap.end(); - it != end; ++it) - { - delete (*it).second; - } - pmap.clear(); - } - - //! Add a heap property to the list - template <typename T> - void AddProperty( const char* name, T* in ){ - AddProperty(name,(Base*)new THeapData<T>(in)); - } - - //! Add a static by-value property to the list - template <typename T> - void AddProperty( const char* name, T in ){ - AddProperty(name,(Base*)new TStaticData<T>(in)); - } - - - //! Get a heap property - template <typename T> - bool GetProperty( const char* name, T*& out ) const - { - THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name); - if(!t) - { - out = NULL; - return false; - } - out = t->data; - return true; - } - - //! Get a static, by-value property - template <typename T> - bool GetProperty( const char* name, T& out ) const - { - TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name); - if(!t)return false; - out = t->data; - return true; - } - - //! Remove a property of a specific type - void RemoveProperty( const char* name) { - SetGenericPropertyPtr<Base>(pmap,name,NULL); - } - -private: - - void AddProperty( const char* name, Base* data) { - SetGenericPropertyPtr<Base>(pmap,name,data); - } - - Base* GetPropertyInternal( const char* name) const { - return GetGenericProperty<Base*>(pmap,name,NULL); - } - -private: - - //! Map of all stored properties - PropertyMap pmap; -}; - -#if 0 - -// --------------------------------------------------------------------------- -/** @brief Represents a dependency table for a postprocessing steps. - * - * For future use. - */ - struct PPDependencyTable - { - unsigned int execute_me_before_these; - unsigned int execute_me_after_these; - unsigned int only_if_these_are_not_specified; - unsigned int mutually_exclusive_with; - }; - -#endif - - -#define AI_SPP_SPATIAL_SORT "$Spat" - -// --------------------------------------------------------------------------- -/** The BaseProcess defines a common interface for all post processing steps. - * A post processing step is run after a successful import if the caller - * specified the corresponding flag when calling ReadFile(). - * Enum #aiPostProcessSteps defines which flags are available. - * After a successful import the Importer iterates over its internal array - * of processes and calls IsActive() on each process to evaluate if the step - * should be executed. If the function returns true, the class' Execute() - * function is called subsequently. - */ -class ASSIMP_API_WINONLY BaseProcess { - friend class Importer; - -public: - /** Constructor to be privately used by Importer */ - BaseProcess() AI_NO_EXCEPT; - - /** Destructor, private as well */ - virtual ~BaseProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. A - * bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - virtual bool IsActive( unsigned int pFlags) const = 0; - - // ------------------------------------------------------------------- - /** Check whether this step expects its input vertex data to be - * in verbose format. */ - virtual bool RequireVerboseFormat() const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * The function deletes the scene if the postprocess step fails ( - * the object pointer will be set to NULL). - * @param pImp Importer instance (pImp->mScene must be valid) - */ - void ExecuteOnScene( Importer* pImp); - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - virtual void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * A process should throw an ImportErrorException* if it fails. - * This method must be implemented by deriving classes. - * @param pScene The imported data to work at. - */ - virtual void Execute( aiScene* pScene) = 0; - - - // ------------------------------------------------------------------- - /** Assign a new SharedPostProcessInfo to the step. This object - * allows multiple postprocess steps to share data. - * @param sh May be NULL - */ - inline void SetSharedData(SharedPostProcessInfo* sh) { - shared = sh; - } - - // ------------------------------------------------------------------- - /** Get the shared data that is assigned to the step. - */ - inline SharedPostProcessInfo* GetSharedData() { - return shared; - } - -protected: - - /** See the doc of #SharedPostProcessInfo for more details */ - SharedPostProcessInfo* shared; - - /** Currently active progress handler */ - ProgressHandler* progress; -}; - - -} // end of namespace Assimp - -#endif // AI_BASEPROCESS_H_INC diff --git a/thirdparty/assimp/code/Common/Bitmap.cpp b/thirdparty/assimp/code/Common/Bitmap.cpp deleted file mode 100644 index b22b71ea9e..0000000000 --- a/thirdparty/assimp/code/Common/Bitmap.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Bitmap.cpp - * @brief Defines bitmap format helper for textures - * - * Used for file formats which embed their textures into the model file. - */ - - -#include <assimp/Bitmap.h> -#include <assimp/texture.h> -#include <assimp/IOStream.hpp> -#include <assimp/ByteSwapper.h> - -namespace Assimp { - - void Bitmap::Save(aiTexture* texture, IOStream* file) { - if(file != NULL) { - Header header; - DIB dib; - - dib.size = DIB::dib_size; - dib.width = texture->mWidth; - dib.height = texture->mHeight; - dib.planes = 1; - dib.bits_per_pixel = 8 * mBytesPerPixel; - dib.compression = 0; - dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height; - dib.x_resolution = 0; - dib.y_resolution = 0; - dib.nb_colors = 0; - dib.nb_important_colors = 0; - - header.type = 0x4D42; // 'BM' - header.offset = Header::header_size + DIB::dib_size; - header.size = header.offset + dib.image_size; - header.reserved1 = 0; - header.reserved2 = 0; - - WriteHeader(header, file); - WriteDIB(dib, file); - WriteData(texture, file); - } - } - - template<typename T> - inline - std::size_t Copy(uint8_t* data, const T &field) { -#ifdef AI_BUILD_BIG_ENDIAN - T field_swapped=AI_BE(field); - std::memcpy(data, &field_swapped, sizeof(field)); return sizeof(field); -#else - std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field); -#endif - } - - void Bitmap::WriteHeader(Header& header, IOStream* file) { - uint8_t data[Header::header_size]; - - std::size_t offset = 0; - - offset += Copy(&data[offset], header.type); - offset += Copy(&data[offset], header.size); - offset += Copy(&data[offset], header.reserved1); - offset += Copy(&data[offset], header.reserved2); - Copy(&data[offset], header.offset); - - file->Write(data, Header::header_size, 1); - } - - void Bitmap::WriteDIB(DIB& dib, IOStream* file) { - uint8_t data[DIB::dib_size]; - - std::size_t offset = 0; - - offset += Copy(&data[offset], dib.size); - offset += Copy(&data[offset], dib.width); - offset += Copy(&data[offset], dib.height); - offset += Copy(&data[offset], dib.planes); - offset += Copy(&data[offset], dib.bits_per_pixel); - offset += Copy(&data[offset], dib.compression); - offset += Copy(&data[offset], dib.image_size); - offset += Copy(&data[offset], dib.x_resolution); - offset += Copy(&data[offset], dib.y_resolution); - offset += Copy(&data[offset], dib.nb_colors); - Copy(&data[offset], dib.nb_important_colors); - - file->Write(data, DIB::dib_size, 1); - } - - void Bitmap::WriteData(aiTexture* texture, IOStream* file) { - static const std::size_t padding_offset = 4; - static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0}; - - unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset; - uint8_t pixel[mBytesPerPixel]; - - for(std::size_t i = 0; i < texture->mHeight; ++i) { - for(std::size_t j = 0; j < texture->mWidth; ++j) { - const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format - - pixel[0] = texel.r; - pixel[1] = texel.g; - pixel[2] = texel.b; - pixel[3] = texel.a; - - file->Write(pixel, mBytesPerPixel, 1); - } - - file->Write(padding_data, padding, 1); - } - } - -} diff --git a/thirdparty/assimp/code/Common/CreateAnimMesh.cpp b/thirdparty/assimp/code/Common/CreateAnimMesh.cpp deleted file mode 100644 index 98b60e5319..0000000000 --- a/thirdparty/assimp/code/Common/CreateAnimMesh.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (C) 2016 The Qt Company Ltd. -Copyright (c) 2006-2012, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -#include <assimp/CreateAnimMesh.h> - -namespace Assimp { - -aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh) -{ - aiAnimMesh *animesh = new aiAnimMesh; - animesh->mNumVertices = mesh->mNumVertices; - if (mesh->mVertices) { - animesh->mVertices = new aiVector3D[animesh->mNumVertices]; - std::memcpy(animesh->mVertices, mesh->mVertices, mesh->mNumVertices * sizeof(aiVector3D)); - } - if (mesh->mNormals) { - animesh->mNormals = new aiVector3D[animesh->mNumVertices]; - std::memcpy(animesh->mNormals, mesh->mNormals, mesh->mNumVertices * sizeof(aiVector3D)); - } - if (mesh->mTangents) { - animesh->mTangents = new aiVector3D[animesh->mNumVertices]; - std::memcpy(animesh->mTangents, mesh->mTangents, mesh->mNumVertices * sizeof(aiVector3D)); - } - if (mesh->mBitangents) { - animesh->mBitangents = new aiVector3D[animesh->mNumVertices]; - std::memcpy(animesh->mBitangents, mesh->mBitangents, mesh->mNumVertices * sizeof(aiVector3D)); - } - - for (int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { - if (mesh->mColors[i]) { - animesh->mColors[i] = new aiColor4D[animesh->mNumVertices]; - std::memcpy(animesh->mColors[i], mesh->mColors[i], mesh->mNumVertices * sizeof(aiColor4D)); - } else { - animesh->mColors[i] = NULL; - } - } - - for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (mesh->mTextureCoords[i]) { - animesh->mTextureCoords[i] = new aiVector3D[animesh->mNumVertices]; - std::memcpy(animesh->mTextureCoords[i], mesh->mTextureCoords[i], mesh->mNumVertices * sizeof(aiVector3D)); - } else { - animesh->mTextureCoords[i] = NULL; - } - } - return animesh; -} - -} // end of namespace Assimp diff --git a/thirdparty/assimp/code/Common/DefaultIOStream.cpp b/thirdparty/assimp/code/Common/DefaultIOStream.cpp deleted file mode 100644 index 1c100b6189..0000000000 --- a/thirdparty/assimp/code/Common/DefaultIOStream.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file DefaultIOStream.cpp - * @brief Default File I/O implementation for #Importer - */ - - -#include <assimp/ai_assert.h> -#include <assimp/DefaultIOStream.h> -#include <sys/types.h> -#include <sys/stat.h> - -using namespace Assimp; - -// ---------------------------------------------------------------------------------- -DefaultIOStream::~DefaultIOStream() -{ - if (mFile) { - ::fclose(mFile); - mFile = nullptr; - } -} - -// ---------------------------------------------------------------------------------- -size_t DefaultIOStream::Read(void* pvBuffer, - size_t pSize, - size_t pCount) -{ - ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount); - return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0); -} - -// ---------------------------------------------------------------------------------- -size_t DefaultIOStream::Write(const void* pvBuffer, - size_t pSize, - size_t pCount) -{ - ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount); - return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0); -} - -// ---------------------------------------------------------------------------------- -aiReturn DefaultIOStream::Seek(size_t pOffset, - aiOrigin pOrigin) -{ - if (!mFile) { - return AI_FAILURE; - } - - // Just to check whether our enum maps one to one with the CRT constants - static_assert(aiOrigin_CUR == SEEK_CUR && - aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET, "aiOrigin_CUR == SEEK_CUR && \ - aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET"); - - // do the seek - return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE); -} - -// ---------------------------------------------------------------------------------- -size_t DefaultIOStream::Tell() const -{ - if (!mFile) { - return 0; - } - return ::ftell(mFile); -} - -// ---------------------------------------------------------------------------------- -size_t DefaultIOStream::FileSize() const -{ - if (! mFile || mFilename.empty()) { - return 0; - } - - if (SIZE_MAX == mCachedSize ) { - - // Although fseek/ftell would allow us to reuse the existing file handle here, - // it is generally unsafe because: - // - For binary streams, it is not technically well-defined - // - For text files the results are meaningless - // That's why we use the safer variant fstat here. - // - // See here for details: - // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file -#if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601) - struct __stat64 fileStat; - //using fileno + fstat avoids having to handle the filename - int err = _fstat64( _fileno(mFile), &fileStat ); - if (0 != err) - return 0; - mCachedSize = (size_t) (fileStat.st_size); -#elif defined __GNUC__ || defined __APPLE__ || defined __MACH__ || defined __FreeBSD__ - struct stat fileStat; - int err = stat(mFilename.c_str(), &fileStat ); - if (0 != err) - return 0; - const unsigned long long cachedSize = fileStat.st_size; - mCachedSize = static_cast< size_t >( cachedSize ); -#else -# error "Unknown platform" -#endif - } - return mCachedSize; -} - -// ---------------------------------------------------------------------------------- -void DefaultIOStream::Flush() -{ - if (mFile) { - ::fflush(mFile); - } -} - -// ---------------------------------------------------------------------------------- diff --git a/thirdparty/assimp/code/Common/DefaultIOSystem.cpp b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp deleted file mode 100644 index 6fdc24dd80..0000000000 --- a/thirdparty/assimp/code/Common/DefaultIOSystem.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file Default implementation of IOSystem using the standard C file functions */ - -#include <assimp/StringComparison.h> - -#include <assimp/DefaultIOSystem.h> -#include <assimp/DefaultIOStream.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/ai_assert.h> -#include <stdlib.h> - -#ifdef __unix__ -#include <sys/param.h> -#include <stdlib.h> -#endif - -#ifdef _WIN32 -#include <windows.h> -#endif - -using namespace Assimp; - -#ifdef _WIN32 -static std::wstring Utf8ToWide(const char* in) -{ - int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0); - // size includes terminating null; std::wstring adds null automatically - std::wstring out(static_cast<size_t>(size) - 1, L'\0'); - MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size); - return out; -} - -static std::string WideToUtf8(const wchar_t* in) -{ - int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr); - // size includes terminating null; std::string adds null automatically - std::string out(static_cast<size_t>(size) - 1, '\0'); - WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr); - return out; -} -#endif - -// ------------------------------------------------------------------------------------------------ -// Tests for the existence of a file at the given path. -bool DefaultIOSystem::Exists(const char* pFile) const -{ -#ifdef _WIN32 - struct __stat64 filestat; - if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) { - return false; - } -#else - FILE* file = ::fopen(pFile, "rb"); - if (!file) - return false; - - ::fclose(file); -#endif - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Open a new file with a given path. -IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode) -{ - ai_assert(strFile != nullptr); - ai_assert(strMode != nullptr); - FILE* file; -#ifdef _WIN32 - file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str()); -#else - file = ::fopen(strFile, strMode); -#endif - if (!file) - return nullptr; - - return new DefaultIOStream(file, strFile); -} - -// ------------------------------------------------------------------------------------------------ -// Closes the given file and releases all resources associated with it. -void DefaultIOSystem::Close(IOStream* pFile) -{ - delete pFile; -} - -// ------------------------------------------------------------------------------------------------ -// Returns the operation specific directory separator -char DefaultIOSystem::getOsSeparator() const -{ -#ifndef _WIN32 - return '/'; -#else - return '\\'; -#endif -} - -// ------------------------------------------------------------------------------------------------ -// IOSystem default implementation (ComparePaths isn't a pure virtual function) -bool IOSystem::ComparePaths(const char* one, const char* second) const -{ - return !ASSIMP_stricmp(one, second); -} - -// ------------------------------------------------------------------------------------------------ -// Convert a relative path into an absolute path -inline static std::string MakeAbsolutePath(const char* in) -{ - ai_assert(in); - std::string out; -#ifdef _WIN32 - wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0); - if (ret) { - out = WideToUtf8(ret); - free(ret); - } -#else - char* ret = realpath(in, nullptr); - if (ret) { - out = ret; - free(ret); - } -#endif - if (!ret) { - // preserve the input path, maybe someone else is able to fix - // the path before it is accessed (e.g. our file system filter) - ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); - out = in; - } - return out; -} - -// ------------------------------------------------------------------------------------------------ -// DefaultIOSystem's more specialized implementation -bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const -{ - // chances are quite good both paths are formatted identically, - // so we can hopefully return here already - if (!ASSIMP_stricmp(one, second)) - return true; - - std::string temp1 = MakeAbsolutePath(one); - std::string temp2 = MakeAbsolutePath(second); - - return !ASSIMP_stricmp(temp1, temp2); -} - -// ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::fileName(const std::string& path) -{ - std::string ret = path; - std::size_t last = ret.find_last_of("\\/"); - if (last != std::string::npos) ret = ret.substr(last + 1); - return ret; -} - -// ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::completeBaseName(const std::string& path) -{ - std::string ret = fileName(path); - std::size_t pos = ret.find_last_of('.'); - if (pos != std::string::npos) ret = ret.substr(0, pos); - return ret; -} - -// ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::absolutePath(const std::string& path) -{ - std::string ret = path; - std::size_t last = ret.find_last_of("\\/"); - if (last != std::string::npos) ret = ret.substr(0, last); - return ret; -} - -// ------------------------------------------------------------------------------------------------ diff --git a/thirdparty/assimp/code/Common/DefaultLogger.cpp b/thirdparty/assimp/code/Common/DefaultLogger.cpp deleted file mode 100644 index de3528d2b4..0000000000 --- a/thirdparty/assimp/code/Common/DefaultLogger.cpp +++ /dev/null @@ -1,418 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file DefaultLogger.cpp - * @brief Implementation of DefaultLogger (and Logger) - */ - -// Default log streams -#include "Win32DebugLogStream.h" -#include "StdOStreamLogStream.h" -#include "FileLogStream.h" -#include <assimp/StringUtils.h> - -#include <assimp/DefaultIOSystem.h> -#include <assimp/NullLogger.hpp> -#include <assimp/DefaultLogger.hpp> -#include <assimp/ai_assert.h> -#include <iostream> -#include <stdio.h> - -#ifndef ASSIMP_BUILD_SINGLETHREADED -# include <thread> -# include <mutex> - std::mutex loggerMutex; -#endif - -namespace Assimp { - -// ---------------------------------------------------------------------------------- -NullLogger DefaultLogger::s_pNullLogger; -Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger; - -static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging; - -// ---------------------------------------------------------------------------------- -// Represents a log-stream + its error severity -struct LogStreamInfo { - unsigned int m_uiErrorSeverity; - LogStream *m_pStream; - - // Constructor - LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) : - m_uiErrorSeverity( uiErrorSev ), - m_pStream( pStream ) { - // empty - } - - // Destructor - ~LogStreamInfo() { - delete m_pStream; - } -}; - -// ---------------------------------------------------------------------------------- -// Construct a default log stream -LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams, - const char* name /*= "AssimpLog.txt"*/, - IOSystem* io /*= NULL*/) -{ - switch (streams) - { - // This is a platform-specific feature - case aiDefaultLogStream_DEBUGGER: -#ifdef WIN32 - return new Win32DebugLogStream(); -#else - return nullptr; -#endif - - // Platform-independent default streams - case aiDefaultLogStream_STDERR: - return new StdOStreamLogStream(std::cerr); - case aiDefaultLogStream_STDOUT: - return new StdOStreamLogStream(std::cout); - case aiDefaultLogStream_FILE: - return (name && *name ? new FileLogStream(name,io) : nullptr ); - default: - // We don't know this default log stream, so raise an assertion - ai_assert(false); - - }; - - // For compilers without dead code path detection - return NULL; -} - -// ---------------------------------------------------------------------------------- -// Creates the only singleton instance -Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/, - LogSeverity severity /*= NORMAL*/, - unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/, - IOSystem* io /*= NULL*/) { - // enter the mutex here to avoid concurrency problems -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(loggerMutex); -#endif - - if ( m_pLogger && !isNullLogger() ) { - delete m_pLogger; - } - - m_pLogger = new DefaultLogger( severity ); - - // Attach default log streams - // Stream the log to the MSVC debugger? - if ( defStreams & aiDefaultLogStream_DEBUGGER ) { - m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_DEBUGGER ) ); - } - - // Stream the log to COUT? - if ( defStreams & aiDefaultLogStream_STDOUT ) { - m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_STDOUT ) ); - } - - // Stream the log to CERR? - if ( defStreams & aiDefaultLogStream_STDERR ) { - m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_STDERR ) ); - } - - // Stream the log to a file - if ( defStreams & aiDefaultLogStream_FILE && name && *name ) { - m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_FILE, name, io ) ); - } - - return m_pLogger; -} - -// ---------------------------------------------------------------------------------- -void Logger::debug(const char* message) { - - // SECURITY FIX: otherwise it's easy to produce overruns since - // sometimes importers will include data from the input file - // (i.e. node names) in their messages. - if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { - return; - } - return OnDebug(message); -} - -// ---------------------------------------------------------------------------------- -void Logger::info(const char* message) { - - // SECURITY FIX: see above - if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { - return; - } - return OnInfo(message); -} - -// ---------------------------------------------------------------------------------- -void Logger::warn(const char* message) { - - // SECURITY FIX: see above - if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { - return; - } - return OnWarn(message); -} - -// ---------------------------------------------------------------------------------- -void Logger::error(const char* message) { - // SECURITY FIX: see above - if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { - return; - } - return OnError(message); -} - -// ---------------------------------------------------------------------------------- -void DefaultLogger::set( Logger *logger ) { - // enter the mutex here to avoid concurrency problems -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(loggerMutex); -#endif - - if ( nullptr == logger ) { - logger = &s_pNullLogger; - } - if ( nullptr != m_pLogger && !isNullLogger() ) { - delete m_pLogger; - } - - DefaultLogger::m_pLogger = logger; -} - -// ---------------------------------------------------------------------------------- -bool DefaultLogger::isNullLogger() { - return m_pLogger == &s_pNullLogger; -} - -// ---------------------------------------------------------------------------------- -Logger *DefaultLogger::get() { - return m_pLogger; -} - -// ---------------------------------------------------------------------------------- -// Kills the only instance -void DefaultLogger::kill() { - // enter the mutex here to avoid concurrency problems -#ifndef ASSIMP_BUILD_SINGLETHREADED - std::lock_guard<std::mutex> lock(loggerMutex); -#endif - - if ( m_pLogger == &s_pNullLogger ) { - return; - } - delete m_pLogger; - m_pLogger = &s_pNullLogger; -} - -// ---------------------------------------------------------------------------------- -// Debug message -void DefaultLogger::OnDebug( const char* message ) { - if ( m_Severity == Logger::NORMAL ) { - return; - } - - static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16; - char msg[Size]; - ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message); - - WriteToStreams( msg, Logger::Debugging ); -} - -// ---------------------------------------------------------------------------------- -// Logs an info -void DefaultLogger::OnInfo( const char* message ){ - static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16; - char msg[Size]; - ai_snprintf(msg, Size, "Info, T%u: %s", GetThreadID(), message ); - - WriteToStreams( msg , Logger::Info ); -} - -// ---------------------------------------------------------------------------------- -// Logs a warning -void DefaultLogger::OnWarn( const char* message ) { - static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16; - char msg[Size]; - ai_snprintf(msg, Size, "Warn, T%u: %s", GetThreadID(), message ); - - WriteToStreams( msg, Logger::Warn ); -} - -// ---------------------------------------------------------------------------------- -// Logs an error -void DefaultLogger::OnError( const char* message ) { - static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16; - char msg[ Size ]; - ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message ); - - WriteToStreams( msg, Logger::Err ); -} - -// ---------------------------------------------------------------------------------- -// Will attach a new stream -bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity ) { - if ( nullptr == pStream ) { - return false; - } - - if (0 == severity) { - severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging; - } - - for ( StreamIt it = m_StreamArray.begin(); - it != m_StreamArray.end(); - ++it ) - { - if ( (*it)->m_pStream == pStream ) { - (*it)->m_uiErrorSeverity |= severity; - return true; - } - } - - LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream ); - m_StreamArray.push_back( pInfo ); - return true; -} - -// ---------------------------------------------------------------------------------- -// Detach a stream -bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity ) { - if ( nullptr == pStream ) { - return false; - } - - if (0 == severity) { - severity = SeverityAll; - } - - bool res( false ); - for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) { - if ( (*it)->m_pStream == pStream ) { - (*it)->m_uiErrorSeverity &= ~severity; - if ( (*it)->m_uiErrorSeverity == 0 ) { - // don't delete the underlying stream 'cause the caller gains ownership again - (**it).m_pStream = nullptr; - delete *it; - m_StreamArray.erase( it ); - res = true; - break; - } - return true; - } - } - return res; -} - -// ---------------------------------------------------------------------------------- -// Constructor -DefaultLogger::DefaultLogger(LogSeverity severity) - : Logger ( severity ) - , noRepeatMsg (false) - , lastLen( 0 ) { - lastMsg[0] = '\0'; -} - -// ---------------------------------------------------------------------------------- -// Destructor -DefaultLogger::~DefaultLogger() { - for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) { - // also frees the underlying stream, we are its owner. - delete *it; - } -} - -// ---------------------------------------------------------------------------------- -// Writes message to stream -void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev ) { - ai_assert(nullptr != message); - - // Check whether this is a repeated message - if (! ::strncmp( message,lastMsg, lastLen-1)) - { - if (!noRepeatMsg) - { - noRepeatMsg = true; - message = "Skipping one or more lines with the same contents\n"; - } - else return; - } - else - { - // append a new-line character to the message to be printed - lastLen = ::strlen(message); - ::memcpy(lastMsg,message,lastLen+1); - ::strcat(lastMsg+lastLen,"\n"); - - message = lastMsg; - noRepeatMsg = false; - ++lastLen; - } - for ( ConstStreamIt it = m_StreamArray.begin(); - it != m_StreamArray.end(); - ++it) - { - if ( ErrorSev & (*it)->m_uiErrorSeverity ) - (*it)->m_pStream->write( message); - } -} - -// ---------------------------------------------------------------------------------- -// Returns thread id, if not supported only a zero will be returned. -unsigned int DefaultLogger::GetThreadID() -{ - // fixme: we can get this value via std::threads - // std::this_thread::get_id().hash() returns a (big) size_t, not sure if this is useful in this case. -#ifdef WIN32 - return (unsigned int)::GetCurrentThreadId(); -#else - return 0; // not supported -#endif -} - -// ---------------------------------------------------------------------------------- - -} // !namespace Assimp diff --git a/thirdparty/assimp/code/Common/DefaultProgressHandler.h b/thirdparty/assimp/code/Common/DefaultProgressHandler.h deleted file mode 100644 index bd2cce00be..0000000000 --- a/thirdparty/assimp/code/Common/DefaultProgressHandler.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file ProgressHandler.hpp - * @brief Abstract base class 'ProgressHandler'. - */ -#ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H -#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H - -#include <assimp/ProgressHandler.hpp> - -namespace Assimp { - -// ------------------------------------------------------------------------------------ -/** @brief Internal default implementation of the #ProgressHandler interface. */ -class DefaultProgressHandler : public ProgressHandler { - - virtual bool Update(float /*percentage*/) { - return false; - } - - -}; // !class DefaultProgressHandler -} // Namespace Assimp - -#endif diff --git a/thirdparty/assimp/code/Common/Exporter.cpp b/thirdparty/assimp/code/Common/Exporter.cpp deleted file mode 100644 index 4ce1a2bd80..0000000000 --- a/thirdparty/assimp/code/Common/Exporter.cpp +++ /dev/null @@ -1,636 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Exporter.cpp - -Assimp export interface. While it's public interface bears many similarities -to the import interface (in fact, it is largely symmetric), the internal -implementations differs a lot. Exporters are considered stateless and are -simple callbacks which we maintain in a global list along with their -description strings. - -Here we implement only the C++ interface (Assimp::Exporter). -*/ - -#ifndef ASSIMP_BUILD_NO_EXPORT - -#include <assimp/BlobIOSystem.h> -#include <assimp/SceneCombiner.h> -#include <assimp/DefaultIOSystem.h> -#include <assimp/Exporter.hpp> -#include <assimp/mesh.h> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/Exceptional.h> - -#include "Common/DefaultProgressHandler.h" -#include "Common/BaseProcess.h" -#include "Common/ScenePrivate.h" -#include "PostProcessing/CalcTangentsProcess.h" -#include "PostProcessing/MakeVerboseFormat.h" -#include "PostProcessing/JoinVerticesProcess.h" -#include "PostProcessing/ConvertToLHProcess.h" -#include "PostProcessing/PretransformVertices.h" - -#include <memory> - -namespace Assimp { - -// PostStepRegistry.cpp -void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); - -// ------------------------------------------------------------------------------------------------ -// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype -// do not use const, because some exporter need to convert the scene temporary -void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*); -void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* ); -void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportSceneA3D(const char*, IOSystem*, const aiScene*, const ExportProperties*); -void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*); - -// ------------------------------------------------------------------------------------------------ -// global array of all export formats which Assimp supports in its current build -Exporter::ExportFormatEntry gExporters[] = -{ -#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER - Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada ), -#endif - -#ifndef ASSIMP_BUILD_NO_X_EXPORTER - Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile, - aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs ), -#endif - -#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER - Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER - Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj, - aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ), - Exporter::ExportFormatEntry( "objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl, - aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ), -#endif - -#ifndef ASSIMP_BUILD_NO_STL_EXPORTER - Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL, - aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices - ), - Exporter::ExportFormatEntry( "stlb", "Stereolithography (binary)", "stl" , &ExportSceneSTLBinary, - aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices - ), -#endif - -#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER - Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly, - aiProcess_PreTransformVertices - ), - Exporter::ExportFormatEntry( "plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary, - aiProcess_PreTransformVertices - ), -#endif - -#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER - Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS, - aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices ), -#endif - -#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER - Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2, - aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), - Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2, - aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), - Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF, - aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), - Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB, - aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), -#endif - -#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER - Exporter::ExportFormatEntry( "assbin", "Assimp Binary File", "assbin" , &ExportSceneAssbin, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER - Exporter::ExportFormatEntry( "assxml", "Assimp XML Document", "assxml" , &ExportSceneAssxml, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER - Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - Exporter::ExportFormatEntry( "fbx", "Autodesk FBX (binary)", "fbx", &ExportSceneFBX, 0 ), - Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER - Exporter::ExportFormatEntry( "m3d", "Model 3D (binary)", "m3d", &ExportSceneM3D, 0 ), - Exporter::ExportFormatEntry( "a3d", "Model 3D (ascii)", "m3d", &ExportSceneA3D, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER - Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 ), -#endif - -#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER - Exporter::ExportFormatEntry( "assjson", "Assimp JSON Document", "json", &ExportAssimp2Json, 0) -#endif -}; - -#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0])) - - -class ExporterPimpl { -public: - ExporterPimpl() - : blob() - , mIOSystem(new Assimp::DefaultIOSystem()) - , mIsDefaultIOHandler(true) - , mProgressHandler( nullptr ) - , mIsDefaultProgressHandler( true ) - , mPostProcessingSteps() - , mError() - , mExporters() { - GetPostProcessingStepInstanceList(mPostProcessingSteps); - - // grab all built-in exporters - if ( 0 != ( ASSIMP_NUM_EXPORTERS ) ) { - mExporters.resize( ASSIMP_NUM_EXPORTERS ); - std::copy( gExporters, gExporters + ASSIMP_NUM_EXPORTERS, mExporters.begin() ); - } - } - - ~ExporterPimpl() { - delete blob; - - // Delete all post-processing plug-ins - for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) { - delete mPostProcessingSteps[a]; - } - delete mProgressHandler; - } - -public: - aiExportDataBlob* blob; - std::shared_ptr< Assimp::IOSystem > mIOSystem; - bool mIsDefaultIOHandler; - - /** The progress handler */ - ProgressHandler *mProgressHandler; - bool mIsDefaultProgressHandler; - - /** Post processing steps we can apply at the imported data. */ - std::vector< BaseProcess* > mPostProcessingSteps; - - /** Last fatal export error */ - std::string mError; - - /** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */ - std::vector<Exporter::ExportFormatEntry> mExporters; -}; - -} // end of namespace Assimp - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -Exporter :: Exporter() -: pimpl(new ExporterPimpl()) { - pimpl->mProgressHandler = new DefaultProgressHandler(); -} - -// ------------------------------------------------------------------------------------------------ -Exporter::~Exporter() { - FreeBlob(); - delete pimpl; -} - -// ------------------------------------------------------------------------------------------------ -void Exporter::SetIOHandler( IOSystem* pIOHandler) { - pimpl->mIsDefaultIOHandler = !pIOHandler; - pimpl->mIOSystem.reset(pIOHandler); -} - -// ------------------------------------------------------------------------------------------------ -IOSystem* Exporter::GetIOHandler() const { - return pimpl->mIOSystem.get(); -} - -// ------------------------------------------------------------------------------------------------ -bool Exporter::IsDefaultIOHandler() const { - return pimpl->mIsDefaultIOHandler; -} - -// ------------------------------------------------------------------------------------------------ -void Exporter::SetProgressHandler(ProgressHandler* pHandler) { - ai_assert(nullptr != pimpl); - - if ( nullptr == pHandler) { - // Release pointer in the possession of the caller - pimpl->mProgressHandler = new DefaultProgressHandler(); - pimpl->mIsDefaultProgressHandler = true; - return; - } - - if (pimpl->mProgressHandler == pHandler) { - return; - } - - delete pimpl->mProgressHandler; - pimpl->mProgressHandler = pHandler; - pimpl->mIsDefaultProgressHandler = false; -} - -// ------------------------------------------------------------------------------------------------ -const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId, - unsigned int pPreprocessing, const ExportProperties* pProperties) { - if (pimpl->blob) { - delete pimpl->blob; - pimpl->blob = nullptr; - } - - std::shared_ptr<IOSystem> old = pimpl->mIOSystem; - BlobIOSystem* blobio = new BlobIOSystem(); - pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio ); - - if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName(), pPreprocessing, pProperties)) { - pimpl->mIOSystem = old; - return nullptr; - } - - pimpl->blob = blobio->GetBlobChain(); - pimpl->mIOSystem = old; - - return pimpl->blob; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, - unsigned int pPreprocessing, const ExportProperties* pProperties) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // when they create scenes from scratch, users will likely create them not in verbose - // format. They will likely not be aware that there is a flag in the scene to indicate - // this, however. To avoid surprises and bug reports, we check for duplicates in - // meshes upfront. - const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene); - - pimpl->mProgressHandler->UpdateFileWrite(0, 4); - - pimpl->mError = ""; - for (size_t i = 0; i < pimpl->mExporters.size(); ++i) { - const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i]; - if (!strcmp(exp.mDescription.id,pFormatId)) { - try { - // Always create a full copy of the scene. We might optimize this one day, - // but for now it is the most pragmatic way. - aiScene* scenecopy_tmp = nullptr; - SceneCombiner::CopyScene(&scenecopy_tmp,pScene); - - pimpl->mProgressHandler->UpdateFileWrite(1, 4); - - std::unique_ptr<aiScene> scenecopy(scenecopy_tmp); - const ScenePrivateData* const priv = ScenePriv(pScene); - - // steps that are not idempotent, i.e. we might need to run them again, usually to get back to the - // original state before the step was applied first. When checking which steps we don't need - // to run, those are excluded. - const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded; - - // Erase all pp steps that were already applied to this scene - const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy - ? (priv->mPPStepsApplied & ~nonIdempotentSteps) - : 0u); - - // If no extra post-processing was specified, and we obtained this scene from an - // Assimp importer, apply the reverse steps automatically. - // TODO: either drop this, or document it. Otherwise it is just a bad surprise. - //if (!pPreprocessing && priv) { - // pp |= (nonIdempotentSteps & priv->mPPStepsApplied); - //} - - // If the input scene is not in verbose format, but there is at least post-processing step that relies on it, - // we need to run the MakeVerboseFormat step first. - bool must_join_again = false; - if (!is_verbose_format) { - bool verbosify = false; - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - BaseProcess* const p = pimpl->mPostProcessingSteps[a]; - - if (p->IsActive(pp) && p->RequireVerboseFormat()) { - verbosify = true; - break; - } - } - - if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) { - ASSIMP_LOG_DEBUG("export: Scene data not in verbose format, applying MakeVerboseFormat step first"); - - MakeVerboseFormatProcess proc; - proc.Execute(scenecopy.get()); - - if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) { - must_join_again = true; - } - } - } - - pimpl->mProgressHandler->UpdateFileWrite(2, 4); - - if (pp) { - // the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout - { - FlipWindingOrderProcess step; - if (step.IsActive(pp)) { - step.Execute(scenecopy.get()); - } - } - - { - FlipUVsProcess step; - if (step.IsActive(pp)) { - step.Execute(scenecopy.get()); - } - } - - { - MakeLeftHandedProcess step; - if (step.IsActive(pp)) { - step.Execute(scenecopy.get()); - } - } - - bool exportPointCloud(false); - if (nullptr != pProperties) { - exportPointCloud = pProperties->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS); - } - - // dispatch other processes - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - BaseProcess* const p = pimpl->mPostProcessingSteps[a]; - - if (p->IsActive(pp) - && !dynamic_cast<FlipUVsProcess*>(p) - && !dynamic_cast<FlipWindingOrderProcess*>(p) - && !dynamic_cast<MakeLeftHandedProcess*>(p)) { - if (dynamic_cast<PretransformVertices*>(p) && exportPointCloud) { - continue; - } - p->Execute(scenecopy.get()); - } - } - ScenePrivateData* const privOut = ScenePriv(scenecopy.get()); - ai_assert(nullptr != privOut); - - privOut->mPPStepsApplied |= pp; - } - - pimpl->mProgressHandler->UpdateFileWrite(3, 4); - - if(must_join_again) { - JoinVerticesProcess proc; - proc.Execute(scenecopy.get()); - } - - ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry. - ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties; - pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again); - exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp); - exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp); - - pimpl->mProgressHandler->UpdateFileWrite(4, 4); - } catch (DeadlyExportError& err) { - pimpl->mError = err.what(); - return AI_FAILURE; - } - return AI_SUCCESS; - } - } - - pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId; - ASSIMP_END_EXCEPTION_REGION(aiReturn); - - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -const char* Exporter::GetErrorString() const { - return pimpl->mError.c_str(); -} - -// ------------------------------------------------------------------------------------------------ -void Exporter::FreeBlob() { - delete pimpl->blob; - pimpl->blob = nullptr; - - pimpl->mError = ""; -} - -// ------------------------------------------------------------------------------------------------ -const aiExportDataBlob* Exporter::GetBlob() const { - return pimpl->blob; -} - -// ------------------------------------------------------------------------------------------------ -const aiExportDataBlob* Exporter::GetOrphanedBlob() const { - const aiExportDataBlob* tmp = pimpl->blob; - pimpl->blob = nullptr; - return tmp; -} - -// ------------------------------------------------------------------------------------------------ -size_t Exporter::GetExportFormatCount() const { - return pimpl->mExporters.size(); -} - -// ------------------------------------------------------------------------------------------------ -const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const { - if (index >= GetExportFormatCount()) { - return nullptr; - } - - // Return from static storage if the requested index is built-in. - if (index < sizeof(gExporters) / sizeof(gExporters[0])) { - return &gExporters[index].mDescription; - } - - return &pimpl->mExporters[index].mDescription; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) { - for(const ExportFormatEntry& e : pimpl->mExporters) { - if (!strcmp(e.mDescription.id,desc.mDescription.id)) { - return aiReturn_FAILURE; - } - } - - pimpl->mExporters.push_back(desc); - return aiReturn_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -void Exporter::UnregisterExporter(const char* id) { - for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); - it != pimpl->mExporters.end(); ++it) { - if (!strcmp((*it).mDescription.id,id)) { - pimpl->mExporters.erase(it); - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -ExportProperties::ExportProperties() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -ExportProperties::ExportProperties(const ExportProperties &other) -: mIntProperties(other.mIntProperties) -, mFloatProperties(other.mFloatProperties) -, mStringProperties(other.mStringProperties) -, mMatrixProperties(other.mMatrixProperties) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool ExportProperties::SetPropertyInteger(const char* szName, int iValue) { - return SetGenericProperty<int>(mIntProperties, szName,iValue); -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool ExportProperties::SetPropertyFloat(const char* szName, ai_real iValue) { - return SetGenericProperty<ai_real>(mFloatProperties, szName,iValue); -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool ExportProperties::SetPropertyString(const char* szName, const std::string& value) { - return SetGenericProperty<std::string>(mStringProperties, szName,value); -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool ExportProperties::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) { - return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value); -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -int ExportProperties::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const { - return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -ai_real ExportProperties::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const { - return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -const std::string ExportProperties::GetPropertyString(const char* szName, - const std::string& iErrorReturn /*= ""*/) const { - return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Has a configuration property -const aiMatrix4x4 ExportProperties::GetPropertyMatrix(const char* szName, - const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const { - return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Has a configuration property -bool ExportProperties::HasPropertyInteger(const char* szName) const { - return HasGenericProperty<int>(mIntProperties, szName); -} - -// ------------------------------------------------------------------------------------------------ -// Has a configuration property -bool ExportProperties::HasPropertyBool(const char* szName) const { - return HasGenericProperty<int>(mIntProperties, szName); -} - -// ------------------------------------------------------------------------------------------------ -// Has a configuration property -bool ExportProperties::HasPropertyFloat(const char* szName) const { - return HasGenericProperty<ai_real>(mFloatProperties, szName); -} - -// ------------------------------------------------------------------------------------------------ -// Has a configuration property -bool ExportProperties::HasPropertyString(const char* szName) const { - return HasGenericProperty<std::string>(mStringProperties, szName); -} - -// ------------------------------------------------------------------------------------------------ -// Has a configuration property -bool ExportProperties::HasPropertyMatrix(const char* szName) const { - return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName); -} - - -#endif // !ASSIMP_BUILD_NO_EXPORT diff --git a/thirdparty/assimp/code/Common/FileLogStream.h b/thirdparty/assimp/code/Common/FileLogStream.h deleted file mode 100644 index 740c503192..0000000000 --- a/thirdparty/assimp/code/Common/FileLogStream.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -/** @file FileLofStream.h -*/ -#ifndef ASSIMP_FILELOGSTREAM_H_INC -#define ASSIMP_FILELOGSTREAM_H_INC - -#include <assimp/LogStream.hpp> -#include <assimp/IOStream.hpp> -#include <assimp/DefaultIOSystem.h> - -namespace Assimp { - -// ---------------------------------------------------------------------------------- -/** @class FileLogStream - * @brief Logstream to write into a file. - */ -class FileLogStream : - public LogStream -{ -public: - FileLogStream( const char* file, IOSystem* io = NULL ); - ~FileLogStream(); - void write( const char* message ); - -private: - IOStream *m_pStream; -}; - -// ---------------------------------------------------------------------------------- -// Constructor -inline FileLogStream::FileLogStream( const char* file, IOSystem* io ) : - m_pStream(NULL) -{ - if ( !file || 0 == *file ) - return; - - // If no IOSystem is specified: take a default one - if (!io) - { - DefaultIOSystem FileSystem; - m_pStream = FileSystem.Open( file, "wt"); - } - else m_pStream = io->Open( file, "wt" ); -} - -// ---------------------------------------------------------------------------------- -// Destructor -inline FileLogStream::~FileLogStream() -{ - // The virtual d'tor should destroy the underlying file - delete m_pStream; -} - -// ---------------------------------------------------------------------------------- -// Write method -inline void FileLogStream::write( const char* message ) -{ - if (m_pStream != NULL) - { - m_pStream->Write(message, sizeof(char), ::strlen(message)); - m_pStream->Flush(); - } -} - -// ---------------------------------------------------------------------------------- -} // !Namespace Assimp - -#endif // !! ASSIMP_FILELOGSTREAM_H_INC diff --git a/thirdparty/assimp/code/Common/FileSystemFilter.h b/thirdparty/assimp/code/Common/FileSystemFilter.h deleted file mode 100644 index 9923cdbdd3..0000000000 --- a/thirdparty/assimp/code/Common/FileSystemFilter.h +++ /dev/null @@ -1,345 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2008, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FileSystemFilter.h - * Implements a filter system to filter calls to Exists() and Open() - * in order to improve the success rate of file opening ... - */ -#pragma once -#ifndef AI_FILESYSTEMFILTER_H_INC -#define AI_FILESYSTEMFILTER_H_INC - -#include <assimp/IOSystem.hpp> -#include <assimp/DefaultLogger.hpp> -#include <assimp/fast_atof.h> -#include <assimp/ParsingUtils.h> - -namespace Assimp { - -inline bool IsHex(char s) { - return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F'); -} - -// --------------------------------------------------------------------------- -/** File system filter - */ -class FileSystemFilter : public IOSystem -{ -public: - /** Constructor. */ - FileSystemFilter(const std::string& file, IOSystem* old) - : mWrapped (old) - , mSrc_file(file) - , mSep(mWrapped->getOsSeparator()) { - ai_assert(nullptr != mWrapped); - - // Determine base directory - mBase = mSrc_file; - std::string::size_type ss2; - if (std::string::npos != (ss2 = mBase.find_last_of("\\/"))) { - mBase.erase(ss2,mBase.length()-ss2); - } else { - mBase = ""; - } - - // make sure the directory is terminated properly - char s; - - if ( mBase.empty() ) { - mBase = "."; - mBase += getOsSeparator(); - } else if ((s = *(mBase.end()-1)) != '\\' && s != '/') { - mBase += getOsSeparator(); - } - - DefaultLogger::get()->info("Import root directory is \'" + mBase + "\'"); - } - - /** Destructor. */ - ~FileSystemFilter() { - // empty - } - - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ - bool Exists( const char* pFile) const { - ai_assert( nullptr != mWrapped ); - - std::string tmp = pFile; - - // Currently this IOSystem is also used to open THE ONE FILE. - if (tmp != mSrc_file) { - BuildPath(tmp); - Cleanup(tmp); - } - - return mWrapped->Exists(tmp); - } - - // ------------------------------------------------------------------- - /** Returns the directory separator. */ - char getOsSeparator() const { - return mSep; - } - - // ------------------------------------------------------------------- - /** Open a new file with a given path. */ - IOStream* Open( const char* pFile, const char* pMode = "rb") { - ai_assert( nullptr != mWrapped ); - if ( nullptr == pFile || nullptr == pMode ) { - return nullptr; - } - - ai_assert( nullptr != pFile ); - ai_assert( nullptr != pMode ); - - // First try the unchanged path - IOStream* s = mWrapped->Open(pFile,pMode); - - if (nullptr == s) { - std::string tmp = pFile; - - // Try to convert between absolute and relative paths - BuildPath(tmp); - s = mWrapped->Open(tmp,pMode); - - if (nullptr == s) { - // Finally, look for typical issues with paths - // and try to correct them. This is our last - // resort. - tmp = pFile; - Cleanup(tmp); - BuildPath(tmp); - s = mWrapped->Open(tmp,pMode); - } - } - - return s; - } - - // ------------------------------------------------------------------- - /** Closes the given file and releases all resources associated with it. */ - void Close( IOStream* pFile) { - ai_assert( nullptr != mWrapped ); - return mWrapped->Close(pFile); - } - - // ------------------------------------------------------------------- - /** Compare two paths */ - bool ComparePaths (const char* one, const char* second) const { - ai_assert( nullptr != mWrapped ); - return mWrapped->ComparePaths (one,second); - } - - // ------------------------------------------------------------------- - /** Pushes a new directory onto the directory stack. */ - bool PushDirectory(const std::string &path ) { - ai_assert( nullptr != mWrapped ); - return mWrapped->PushDirectory(path); - } - - // ------------------------------------------------------------------- - /** Returns the top directory from the stack. */ - const std::string &CurrentDirectory() const { - ai_assert( nullptr != mWrapped ); - return mWrapped->CurrentDirectory(); - } - - // ------------------------------------------------------------------- - /** Returns the number of directories stored on the stack. */ - size_t StackSize() const { - ai_assert( nullptr != mWrapped ); - return mWrapped->StackSize(); - } - - // ------------------------------------------------------------------- - /** Pops the top directory from the stack. */ - bool PopDirectory() { - ai_assert( nullptr != mWrapped ); - return mWrapped->PopDirectory(); - } - - // ------------------------------------------------------------------- - /** Creates an new directory at the given path. */ - bool CreateDirectory(const std::string &path) { - ai_assert( nullptr != mWrapped ); - return mWrapped->CreateDirectory(path); - } - - // ------------------------------------------------------------------- - /** Will change the current directory to the given path. */ - bool ChangeDirectory(const std::string &path) { - ai_assert( nullptr != mWrapped ); - return mWrapped->ChangeDirectory(path); - } - - // ------------------------------------------------------------------- - /** Delete file. */ - bool DeleteFile(const std::string &file) { - ai_assert( nullptr != mWrapped ); - return mWrapped->DeleteFile(file); - } - -private: - // ------------------------------------------------------------------- - /** Build a valid path from a given relative or absolute path. - */ - void BuildPath (std::string& in) const { - ai_assert( nullptr != mWrapped ); - // if we can already access the file, great. - if (in.length() < 3 || mWrapped->Exists(in)) { - return; - } - - // Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows). - if (in[1] != ':') { - - // append base path and try - const std::string tmp = mBase + in; - if (mWrapped->Exists(tmp)) { - in = tmp; - return; - } - } - - // Chop of the file name and look in the model directory, if - // this fails try all sub paths of the given path, i.e. - // if the given path is foo/bar/something.lwo, try - // <base>/something.lwo - // <base>/bar/something.lwo - // <base>/foo/bar/something.lwo - std::string::size_type pos = in.rfind('/'); - if (std::string::npos == pos) { - pos = in.rfind('\\'); - } - - if (std::string::npos != pos) { - std::string tmp; - std::string::size_type last_dirsep = std::string::npos; - - while(true) { - tmp = mBase; - tmp += mSep; - - std::string::size_type dirsep = in.rfind('/', last_dirsep); - if (std::string::npos == dirsep) { - dirsep = in.rfind('\\', last_dirsep); - } - - if (std::string::npos == dirsep || dirsep == 0) { - // we did try this already. - break; - } - - last_dirsep = dirsep-1; - - tmp += in.substr(dirsep+1, in.length()-pos); - if (mWrapped->Exists(tmp)) { - in = tmp; - return; - } - } - } - - // hopefully the underlying file system has another few tricks to access this file ... - } - - // ------------------------------------------------------------------- - /** Cleanup the given path - */ - void Cleanup (std::string& in) const { - if(in.empty()) { - return; - } - - // Remove a very common issue when we're parsing file names: spaces at the - // beginning of the path. - char last = 0; - std::string::iterator it = in.begin(); - while (IsSpaceOrNewLine( *it ))++it; - if (it != in.begin()) { - in.erase(in.begin(),it+1); - } - - const char separator = getOsSeparator(); - for (it = in.begin(); it != in.end(); ++it) { - // Exclude :// and \\, which remain untouched. - // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 - if ( !strncmp(&*it, "://", 3 )) { - it += 3; - continue; - } - if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) { - it += 2; - continue; - } - - // Cleanup path delimiters - if (*it == '/' || (*it) == '\\') { - *it = separator; - - // And we're removing double delimiters, frequent issue with - // incorrectly composited paths ... - if (last == *it) { - it = in.erase(it); - --it; - } - } else if (*it == '%' && in.end() - it > 2) { - // Hex sequence in URIs - if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) { - *it = HexOctetToDecimal(&*it); - it = in.erase(it+1,it+2); - --it; - } - } - - last = *it; - } - } - -private: - IOSystem *mWrapped; - std::string mSrc_file, mBase; - char mSep; -}; - -} //!ns Assimp - -#endif //AI_DEFAULTIOSYSTEM_H_INC diff --git a/thirdparty/assimp/code/Common/IFF.h b/thirdparty/assimp/code/Common/IFF.h deleted file mode 100644 index 91d7d48289..0000000000 --- a/thirdparty/assimp/code/Common/IFF.h +++ /dev/null @@ -1,102 +0,0 @@ -// Definitions for the Interchange File Format (IFF) -// Alexander Gessler, 2006 -// Adapted to Assimp August 2008 - -#ifndef AI_IFF_H_INCLUDED -#define AI_IFF_H_INCLUDED - -#include <assimp/ByteSwapper.h> - -namespace Assimp { -namespace IFF { - -///////////////////////////////////////////////////////////////////////////////// -//! Describes an IFF chunk header -///////////////////////////////////////////////////////////////////////////////// -struct ChunkHeader -{ - //! Type of the chunk header - FourCC - uint32_t type; - - //! Length of the chunk data, in bytes - uint32_t length; -}; - - -///////////////////////////////////////////////////////////////////////////////// -//! Describes an IFF sub chunk header -///////////////////////////////////////////////////////////////////////////////// -struct SubChunkHeader -{ - //! Type of the chunk header - FourCC - uint32_t type; - - //! Length of the chunk data, in bytes - uint16_t length; -}; - - -#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \ - ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d))) - - -#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M') - - -///////////////////////////////////////////////////////////////////////////////// -//! Load a chunk header -//! @param outFile Pointer to the file data - points to the chunk data afterwards -//! @return Copy of the chunk header -///////////////////////////////////////////////////////////////////////////////// -inline ChunkHeader LoadChunk(uint8_t*& outFile) -{ - ChunkHeader head; - ::memcpy(&head.type, outFile, 4); - outFile += 4; - ::memcpy(&head.length, outFile, 4); - outFile += 4; - AI_LSWAP4(head.length); - AI_LSWAP4(head.type); - return head; -} - -///////////////////////////////////////////////////////////////////////////////// -//! Load a sub chunk header -//! @param outFile Pointer to the file data - points to the chunk data afterwards -//! @return Copy of the sub chunk header -///////////////////////////////////////////////////////////////////////////////// -inline SubChunkHeader LoadSubChunk(uint8_t*& outFile) -{ - SubChunkHeader head; - ::memcpy(&head.type, outFile, 4); - outFile += 4; - ::memcpy(&head.length, outFile, 2); - outFile += 2; - AI_LSWAP2(head.length); - AI_LSWAP4(head.type); - return head; -} - -///////////////////////////////////////////////////////////////////////////////// -//! Read the file header and return the type of the file and its size -//! @param outFile Pointer to the file data. The buffer must at -//! least be 12 bytes large. -//! @param fileType Receives the type of the file -//! @return 0 if everything was OK, otherwise an error message -///////////////////////////////////////////////////////////////////////////////// -inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType) -{ - ChunkHeader head = LoadChunk(outFile); - if(AI_IFF_FOURCC_FORM != head.type) - { - return "The file is not an IFF file: FORM chunk is missing"; - } - ::memcpy(&fileType, outFile, 4); - AI_LSWAP4(fileType); - return 0; -} - - -}} - -#endif // !! AI_IFF_H_INCLUDED diff --git a/thirdparty/assimp/code/Common/Importer.cpp b/thirdparty/assimp/code/Common/Importer.cpp deleted file mode 100644 index 91b50859a0..0000000000 --- a/thirdparty/assimp/code/Common/Importer.cpp +++ /dev/null @@ -1,1174 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Importer.cpp - * @brief Implementation of the CPP-API class #Importer - */ - -#include <assimp/version.h> -#include <assimp/config.h> -#include <assimp/importerdesc.h> - -// ------------------------------------------------------------------------------------------------ -/* Uncomment this line to prevent Assimp from catching unknown exceptions. - * - * Note that any Exception except DeadlyImportError may lead to - * undefined behaviour -> loaders could remain in an unusable state and - * further imports with the same Importer instance could fail/crash/burn ... - */ -// ------------------------------------------------------------------------------------------------ -#ifndef ASSIMP_BUILD_DEBUG -# define ASSIMP_CATCH_GLOBAL_EXCEPTIONS -#endif - -// ------------------------------------------------------------------------------------------------ -// Internal headers -// ------------------------------------------------------------------------------------------------ -#include "Common/Importer.h" -#include "Common/BaseProcess.h" -#include "Common/DefaultProgressHandler.h" -#include "PostProcessing/ProcessHelper.h" -#include "Common/ScenePreprocessor.h" -#include "Common/ScenePrivate.h" - -#include <assimp/BaseImporter.h> -#include <assimp/GenericProperty.h> -#include <assimp/MemoryIOWrapper.h> -#include <assimp/Profiler.h> -#include <assimp/TinyFormatter.h> -#include <assimp/Exceptional.h> -#include <assimp/Profiler.h> -#include <set> -#include <memory> -#include <cctype> - -#include <assimp/DefaultIOStream.h> -#include <assimp/DefaultIOSystem.h> - -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS -# include "PostProcessing/ValidateDataStructure.h" -#endif - -using namespace Assimp::Profiling; -using namespace Assimp::Formatter; - -namespace Assimp { - // ImporterRegistry.cpp - void GetImporterInstanceList(std::vector< BaseImporter* >& out); - void DeleteImporterInstanceList(std::vector< BaseImporter* >& out); - - // PostStepRegistry.cpp - void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); -} - -using namespace Assimp; -using namespace Assimp::Intern; - -// ------------------------------------------------------------------------------------------------ -// Intern::AllocateFromAssimpHeap serves as abstract base class. It overrides -// new and delete (and their array counterparts) of public API classes (e.g. Logger) to -// utilize our DLL heap. -// See http://www.gotw.ca/publications/mill15.htm -// ------------------------------------------------------------------------------------------------ -void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) { - return ::operator new(num_bytes); -} - -void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw() { - try { - return AllocateFromAssimpHeap::operator new( num_bytes ); - } - catch( ... ) { - return NULL; - } -} - -void AllocateFromAssimpHeap::operator delete ( void* data) { - return ::operator delete(data); -} - -void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes) { - return ::operator new[](num_bytes); -} - -void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw() { - try { - return AllocateFromAssimpHeap::operator new[]( num_bytes ); - } - catch( ... ) { - return NULL; - } -} - -void AllocateFromAssimpHeap::operator delete[] ( void* data) { - return ::operator delete[](data); -} - -// ------------------------------------------------------------------------------------------------ -// Importer constructor. -Importer::Importer() - : pimpl( new ImporterPimpl ) { - pimpl->mScene = NULL; - pimpl->mErrorString = ""; - - // Allocate a default IO handler - pimpl->mIOHandler = new DefaultIOSystem; - pimpl->mIsDefaultHandler = true; - pimpl->bExtraVerbose = false; // disable extra verbose mode by default - - pimpl->mProgressHandler = new DefaultProgressHandler(); - pimpl->mIsDefaultProgressHandler = true; - - GetImporterInstanceList(pimpl->mImporter); - GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps); - - // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list. - pimpl->mPPShared = new SharedPostProcessInfo(); - for (std::vector<BaseProcess*>::iterator it = pimpl->mPostProcessingSteps.begin(); - it != pimpl->mPostProcessingSteps.end(); - ++it) { - - (*it)->SetSharedData(pimpl->mPPShared); - } -} - -// ------------------------------------------------------------------------------------------------ -// Destructor of Importer -Importer::~Importer() -{ - // Delete all import plugins - DeleteImporterInstanceList(pimpl->mImporter); - - // Delete all post-processing plug-ins - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) - delete pimpl->mPostProcessingSteps[a]; - - // Delete the assigned IO and progress handler - delete pimpl->mIOHandler; - delete pimpl->mProgressHandler; - - // Kill imported scene. Destructor's should do that recursively - delete pimpl->mScene; - - // Delete shared post-processing data - delete pimpl->mPPShared; - - // and finally the pimpl itself - delete pimpl; -} - -// ------------------------------------------------------------------------------------------------ -// Register a custom post-processing step -aiReturn Importer::RegisterPPStep(BaseProcess* pImp) -{ - ai_assert(NULL != pImp); - ASSIMP_BEGIN_EXCEPTION_REGION(); - - pimpl->mPostProcessingSteps.push_back(pImp); - ASSIMP_LOG_INFO("Registering custom post-processing step"); - - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Register a custom loader plugin -aiReturn Importer::RegisterLoader(BaseImporter* pImp) -{ - ai_assert(NULL != pImp); - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // -------------------------------------------------------------------- - // Check whether we would have two loaders for the same file extension - // This is absolutely OK, but we should warn the developer of the new - // loader that his code will probably never be called if the first - // loader is a bit too lazy in his file checking. - // -------------------------------------------------------------------- - std::set<std::string> st; - std::string baked; - pImp->GetExtensionList(st); - - for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) { - -#ifdef ASSIMP_BUILD_DEBUG - if (IsExtensionSupported(*it)) { - ASSIMP_LOG_WARN_F("The file extension ", *it, " is already in use"); - } -#endif - baked += *it; - } - - // add the loader - pimpl->mImporter.push_back(pImp); - ASSIMP_LOG_INFO_F("Registering custom importer for these file extensions: ", baked); - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Unregister a custom loader plugin -aiReturn Importer::UnregisterLoader(BaseImporter* pImp) -{ - if(!pImp) { - // unregistering a NULL importer is no problem for us ... really! - return AI_SUCCESS; - } - - ASSIMP_BEGIN_EXCEPTION_REGION(); - std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(), - pimpl->mImporter.end(),pImp); - - if (it != pimpl->mImporter.end()) { - pimpl->mImporter.erase(it); - ASSIMP_LOG_INFO("Unregistering custom importer: "); - return AI_SUCCESS; - } - ASSIMP_LOG_WARN("Unable to remove custom importer: I can't find you ..."); - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -// Unregister a custom loader plugin -aiReturn Importer::UnregisterPPStep(BaseProcess* pImp) -{ - if(!pImp) { - // unregistering a NULL ppstep is no problem for us ... really! - return AI_SUCCESS; - } - - ASSIMP_BEGIN_EXCEPTION_REGION(); - std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(), - pimpl->mPostProcessingSteps.end(),pImp); - - if (it != pimpl->mPostProcessingSteps.end()) { - pimpl->mPostProcessingSteps.erase(it); - ASSIMP_LOG_INFO("Unregistering custom post-processing step"); - return AI_SUCCESS; - } - ASSIMP_LOG_WARN("Unable to remove custom post-processing step: I can't find you .."); - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -// Supplies a custom IO handler to the importer to open and access files. -void Importer::SetIOHandler( IOSystem* pIOHandler) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - // If the new handler is zero, allocate a default IO implementation. - if (!pIOHandler) - { - // Release pointer in the possession of the caller - pimpl->mIOHandler = new DefaultIOSystem(); - pimpl->mIsDefaultHandler = true; - } - // Otherwise register the custom handler - else if (pimpl->mIOHandler != pIOHandler) - { - delete pimpl->mIOHandler; - pimpl->mIOHandler = pIOHandler; - pimpl->mIsDefaultHandler = false; - } - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Get the currently set IO handler -IOSystem* Importer::GetIOHandler() const { - return pimpl->mIOHandler; -} - -// ------------------------------------------------------------------------------------------------ -// Check whether a custom IO handler is currently set -bool Importer::IsDefaultIOHandler() const { - return pimpl->mIsDefaultHandler; -} - -// ------------------------------------------------------------------------------------------------ -// Supplies a custom progress handler to get regular callbacks during importing -void Importer::SetProgressHandler ( ProgressHandler* pHandler ) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - // If the new handler is zero, allocate a default implementation. - if (!pHandler) - { - // Release pointer in the possession of the caller - pimpl->mProgressHandler = new DefaultProgressHandler(); - pimpl->mIsDefaultProgressHandler = true; - } - // Otherwise register the custom handler - else if (pimpl->mProgressHandler != pHandler) - { - delete pimpl->mProgressHandler; - pimpl->mProgressHandler = pHandler; - pimpl->mIsDefaultProgressHandler = false; - } - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Get the currently set progress handler -ProgressHandler* Importer::GetProgressHandler() const { - return pimpl->mProgressHandler; -} - -// ------------------------------------------------------------------------------------------------ -// Check whether a custom progress handler is currently set -bool Importer::IsDefaultProgressHandler() const { - return pimpl->mIsDefaultProgressHandler; -} - -// ------------------------------------------------------------------------------------------------ -// Validate post process step flags -bool _ValidateFlags(unsigned int pFlags) -{ - if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) { - ASSIMP_LOG_ERROR("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible"); - return false; - } - if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) { - ASSIMP_LOG_ERROR("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible"); - return false; - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Free the current scene -void Importer::FreeScene( ) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - - delete pimpl->mScene; - pimpl->mScene = NULL; - - pimpl->mErrorString = ""; - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Get the current error string, if any -const char* Importer::GetErrorString() const -{ - /* Must remain valid as long as ReadFile() or FreeFile() are not called */ - return pimpl->mErrorString.c_str(); -} - -// ------------------------------------------------------------------------------------------------ -// Enable extra-verbose mode -void Importer::SetExtraVerbose(bool bDo) -{ - pimpl->bExtraVerbose = bDo; -} - -// ------------------------------------------------------------------------------------------------ -// Get the current scene -const aiScene* Importer::GetScene() const -{ - return pimpl->mScene; -} - -// ------------------------------------------------------------------------------------------------ -// Orphan the current scene and return it. -aiScene* Importer::GetOrphanedScene() -{ - aiScene* s = pimpl->mScene; - - ASSIMP_BEGIN_EXCEPTION_REGION(); - pimpl->mScene = NULL; - - pimpl->mErrorString = ""; /* reset error string */ - ASSIMP_END_EXCEPTION_REGION(aiScene*); - return s; -} - -// ------------------------------------------------------------------------------------------------ -// Validate post-processing flags -bool Importer::ValidateFlags(unsigned int pFlags) const -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - // run basic checks for mutually exclusive flags - if(!_ValidateFlags(pFlags)) { - return false; - } - - // ValidateDS does not anymore occur in the pp list, it plays an awesome extra role ... -#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - if (pFlags & aiProcess_ValidateDataStructure) { - return false; - } -#endif - pFlags &= ~aiProcess_ValidateDataStructure; - - // Now iterate through all bits which are set in the flags and check whether we find at least - // one pp plugin which handles it. - for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) { - - if (pFlags & mask) { - - bool have = false; - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) { - - have = true; - break; - } - } - if (!have) { - return false; - } - } - } - ASSIMP_END_EXCEPTION_REGION(bool); - return true; -} - -// ------------------------------------------------------------------------------------------------ -const aiScene* Importer::ReadFileFromMemory( const void* pBuffer, - size_t pLength, - unsigned int pFlags, - const char* pHint /*= ""*/) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - if (!pHint) { - pHint = ""; - } - - if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) { - pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()"; - return NULL; - } - - // prevent deletion of the previous IOHandler - IOSystem* io = pimpl->mIOHandler; - pimpl->mIOHandler = NULL; - - SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io)); - - // read the file and recover the previous IOSystem - static const size_t BufSize(Importer::MaxLenHint + 28); - char fbuff[BufSize]; - ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint); - - ReadFile(fbuff,pFlags); - SetIOHandler(io); - - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return pimpl->mScene; -} - -// ------------------------------------------------------------------------------------------------ -void WriteLogOpening(const std::string& file) -{ - ASSIMP_LOG_INFO_F("Load ", file); - - // print a full version dump. This is nice because we don't - // need to ask the authors of incoming bug reports for - // the library version they're using - a log dump is - // sufficient. - const unsigned int flags( aiGetCompileFlags() ); - std::stringstream stream; - stream << "Assimp " << aiGetVersionMajor() << "." << aiGetVersionMinor() << "." << aiGetVersionRevision() << " " -#if defined(ASSIMP_BUILD_ARCHITECTURE) - << ASSIMP_BUILD_ARCHITECTURE -#elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__) - << "x86" -#elif defined(_M_X64) || defined(__x86_64__) - << "amd64" -#elif defined(_M_IA64) || defined(__ia64__) - << "itanium" -#elif defined(__ppc__) || defined(__powerpc__) - << "ppc32" -#elif defined(__powerpc64__) - << "ppc64" -#elif defined(__arm__) - << "arm" -#else - << "<unknown architecture>" -#endif - << " " -#if defined(ASSIMP_BUILD_COMPILER) - << ( ASSIMP_BUILD_COMPILER ) -#elif defined(_MSC_VER) - << "msvc" -#elif defined(__GNUC__) - << "gcc" -#else - << "<unknown compiler>" -#endif - -#ifdef ASSIMP_BUILD_DEBUG - << " debug" -#endif - - << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "") - << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "") - << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : ""); - - ASSIMP_LOG_DEBUG(stream.str()); -} - -// ------------------------------------------------------------------------------------------------ -// Reads the given file and returns its contents if successful. -const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - const std::string pFile(_pFile); - - // ---------------------------------------------------------------------- - // Put a large try block around everything to catch all std::exception's - // that might be thrown by STL containers or by new(). - // ImportErrorException's are throw by ourselves and caught elsewhere. - //----------------------------------------------------------------------- - - WriteLogOpening(pFile); - -#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS - try -#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS - { - // Check whether this Importer instance has already loaded - // a scene. In this case we need to delete the old one - if (pimpl->mScene) { - - ASSIMP_LOG_DEBUG("(Deleting previous scene)"); - FreeScene(); - } - - // First check if the file is accessible at all - if( !pimpl->mIOHandler->Exists( pFile)) { - - pimpl->mErrorString = "Unable to open file \"" + pFile + "\"."; - ASSIMP_LOG_ERROR(pimpl->mErrorString); - return NULL; - } - - std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); - if (profiler) { - profiler->BeginRegion("total"); - } - - // Find an worker class which can handle the file - BaseImporter* imp = NULL; - SetPropertyInteger("importerIndex", -1); - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { - - if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) { - imp = pimpl->mImporter[a]; - SetPropertyInteger("importerIndex", a); - break; - } - } - - if (!imp) { - // not so bad yet ... try format auto detection. - const std::string::size_type s = pFile.find_last_of('.'); - if (s != std::string::npos) { - ASSIMP_LOG_INFO("File extension not known, trying signature-based detection"); - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { - if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) { - imp = pimpl->mImporter[a]; - SetPropertyInteger("importerIndex", a); - break; - } - } - } - // Put a proper error message if no suitable importer was found - if( !imp) { - pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\"."; - ASSIMP_LOG_ERROR(pimpl->mErrorString); - return NULL; - } - } - - // Get file size for progress handler - IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); - uint32_t fileSize = 0; - if (fileIO) - { - fileSize = static_cast<uint32_t>(fileIO->FileSize()); - pimpl->mIOHandler->Close( fileIO ); - } - - // Dispatch the reading to the worker class for this format - const aiImporterDesc *desc( imp->GetInfo() ); - std::string ext( "unknown" ); - if ( NULL != desc ) { - ext = desc->mName; - } - ASSIMP_LOG_INFO("Found a matching importer for this file format: " + ext + "." ); - pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); - - if (profiler) { - profiler->BeginRegion("import"); - } - - pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize ); - - if (profiler) { - profiler->EndRegion("import"); - } - - SetPropertyString("sourceFilePath", pFile); - - // If successful, apply all active post processing steps to the imported data - if( pimpl->mScene) { - -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called. - if (pFlags & aiProcess_ValidateDataStructure) - { - ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if (!pimpl->mScene) { - return NULL; - } - } -#endif // no validation - - // Preprocess the scene and prepare it for post-processing - if (profiler) { - profiler->BeginRegion("preprocess"); - } - - ScenePreprocessor pre(pimpl->mScene); - pre.ProcessScene(); - - if (profiler) { - profiler->EndRegion("preprocess"); - } - - // Ensure that the validation process won't be called twice - ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure)); - } - // if failed, extract the error string - else if( !pimpl->mScene) { - pimpl->mErrorString = imp->GetErrorText(); - } - - // clear any data allocated by post-process steps - pimpl->mPPShared->Clean(); - - if (profiler) { - profiler->EndRegion("total"); - } - } -#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS - catch (std::exception &e) - { -#if (defined _MSC_VER) && (defined _CPPRTTI) - // if we have RTTI get the full name of the exception that occurred - pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what(); -#else - pimpl->mErrorString = std::string("std::exception: ") + e.what(); -#endif - - ASSIMP_LOG_ERROR(pimpl->mErrorString); - delete pimpl->mScene; pimpl->mScene = NULL; - } -#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS - - // either successful or failure - the pointer expresses it anyways - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return pimpl->mScene; -} - - -// ------------------------------------------------------------------------------------------------ -// Apply post-processing to the currently bound scene -const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - // Return immediately if no scene is active - if (!pimpl->mScene) { - return NULL; - } - - // If no flags are given, return the current scene with no further action - if (!pFlags) { - return pimpl->mScene; - } - - // In debug builds: run basic flag validation - ai_assert(_ValidateFlags(pFlags)); - ASSIMP_LOG_INFO("Entering post processing pipeline"); - -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - // The ValidateDS process plays an exceptional role. It isn't contained in the global - // list of post-processing steps, so we need to call it manually. - if (pFlags & aiProcess_ValidateDataStructure) - { - ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if (!pimpl->mScene) { - return NULL; - } - } -#endif // no validation -#ifdef ASSIMP_BUILD_DEBUG - if (pimpl->bExtraVerbose) - { -#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings"); -#endif // no validation - pFlags |= aiProcess_ValidateDataStructure; - } -#else - if (pimpl->bExtraVerbose) { - ASSIMP_LOG_WARN("Not a debug build, ignoring extra verbose setting"); - } -#endif // ! DEBUG - - std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - - BaseProcess* process = pimpl->mPostProcessingSteps[a]; - pimpl->mProgressHandler->UpdatePostProcess(static_cast<int>(a), static_cast<int>(pimpl->mPostProcessingSteps.size()) ); - if( process->IsActive( pFlags)) { - - if (profiler) { - profiler->BeginRegion("postprocess"); - } - - process->ExecuteOnScene ( this ); - - if (profiler) { - profiler->EndRegion("postprocess"); - } - } - if( !pimpl->mScene) { - break; - } -#ifdef ASSIMP_BUILD_DEBUG - -#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - continue; -#endif // no validation - - // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step - if (pimpl->bExtraVerbose) { - ASSIMP_LOG_DEBUG("Verbose Import: re-validating data structures"); - - ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if( !pimpl->mScene) { - ASSIMP_LOG_ERROR("Verbose Import: failed to re-validate data structures"); - break; - } - } -#endif // ! DEBUG - } - pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()), - static_cast<int>(pimpl->mPostProcessingSteps.size()) ); - - // update private scene flags - if( pimpl->mScene ) - ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; - - // clear any data allocated by post-process steps - pimpl->mPPShared->Clean(); - ASSIMP_LOG_INFO("Leaving post processing pipeline"); - - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return pimpl->mScene; -} - -// ------------------------------------------------------------------------------------------------ -const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation ) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // Return immediately if no scene is active - if ( NULL == pimpl->mScene ) { - return NULL; - } - - // If no flags are given, return the current scene with no further action - if ( NULL == rootProcess ) { - return pimpl->mScene; - } - - // In debug builds: run basic flag validation - ASSIMP_LOG_INFO( "Entering customized post processing pipeline" ); - -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - // The ValidateDS process plays an exceptional role. It isn't contained in the global - // list of post-processing steps, so we need to call it manually. - if ( requestValidation ) - { - ValidateDSProcess ds; - ds.ExecuteOnScene( this ); - if ( !pimpl->mScene ) { - return NULL; - } - } -#endif // no validation -#ifdef ASSIMP_BUILD_DEBUG - if ( pimpl->bExtraVerbose ) - { -#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - ASSIMP_LOG_ERROR( "Verbose Import is not available due to build settings" ); -#endif // no validation - } -#else - if ( pimpl->bExtraVerbose ) { - ASSIMP_LOG_WARN( "Not a debug build, ignoring extra verbose setting" ); - } -#endif // ! DEBUG - - std::unique_ptr<Profiler> profiler( GetPropertyInteger( AI_CONFIG_GLOB_MEASURE_TIME, 0 ) ? new Profiler() : NULL ); - - if ( profiler ) { - profiler->BeginRegion( "postprocess" ); - } - - rootProcess->ExecuteOnScene( this ); - - if ( profiler ) { - profiler->EndRegion( "postprocess" ); - } - - // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step - if ( pimpl->bExtraVerbose || requestValidation ) { - ASSIMP_LOG_DEBUG( "Verbose Import: revalidating data structures" ); - - ValidateDSProcess ds; - ds.ExecuteOnScene( this ); - if ( !pimpl->mScene ) { - ASSIMP_LOG_ERROR( "Verbose Import: failed to revalidate data structures" ); - } - } - - // clear any data allocated by post-process steps - pimpl->mPPShared->Clean(); - ASSIMP_LOG_INFO( "Leaving customized post processing pipeline" ); - - ASSIMP_END_EXCEPTION_REGION( const aiScene* ); - - return pimpl->mScene; -} - -// ------------------------------------------------------------------------------------------------ -// Helper function to check whether an extension is supported by ASSIMP -bool Importer::IsExtensionSupported(const char* szExtension) const -{ - return nullptr != GetImporter(szExtension); -} - -// ------------------------------------------------------------------------------------------------ -size_t Importer::GetImporterCount() const -{ - return pimpl->mImporter.size(); -} - -// ------------------------------------------------------------------------------------------------ -const aiImporterDesc* Importer::GetImporterInfo(size_t index) const -{ - if (index >= pimpl->mImporter.size()) { - return NULL; - } - return pimpl->mImporter[index]->GetInfo(); -} - - -// ------------------------------------------------------------------------------------------------ -BaseImporter* Importer::GetImporter (size_t index) const -{ - if (index >= pimpl->mImporter.size()) { - return NULL; - } - return pimpl->mImporter[index]; -} - -// ------------------------------------------------------------------------------------------------ -// Find a loader plugin for a given file extension -BaseImporter* Importer::GetImporter (const char* szExtension) const -{ - return GetImporter(GetImporterIndex(szExtension)); -} - -// ------------------------------------------------------------------------------------------------ -// Find a loader plugin for a given file extension -size_t Importer::GetImporterIndex (const char* szExtension) const { - ai_assert(nullptr != szExtension); - - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // skip over wildcard and dot characters at string head -- - for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension ); - - std::string ext(szExtension); - if (ext.empty()) { - return static_cast<size_t>(-1); - } - std::transform( ext.begin(), ext.end(), ext.begin(), ToLower<char> ); - - std::set<std::string> str; - for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { - str.clear(); - - (*i)->GetExtensionList(str); - for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) { - if (ext == *it) { - return std::distance(static_cast< std::vector<BaseImporter*>::const_iterator >(pimpl->mImporter.begin()), i); - } - } - } - ASSIMP_END_EXCEPTION_REGION(size_t); - return static_cast<size_t>(-1); -} - -// ------------------------------------------------------------------------------------------------ -// Helper function to build a list of all file extensions supported by ASSIMP -void Importer::GetExtensionList(aiString& szOut) const -{ - ASSIMP_BEGIN_EXCEPTION_REGION(); - std::set<std::string> str; - for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { - (*i)->GetExtensionList(str); - } - - // List can be empty - if( !str.empty() ) { - for (std::set<std::string>::const_iterator it = str.begin();; ) { - szOut.Append("*."); - szOut.Append((*it).c_str()); - - if (++it == str.end()) { - break; - } - szOut.Append(";"); - } - } - ASSIMP_END_EXCEPTION_REGION(void); -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool Importer::SetPropertyInteger(const char* szName, int iValue) -{ - bool existing; - ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue); - ASSIMP_END_EXCEPTION_REGION(bool); - return existing; -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool Importer::SetPropertyFloat(const char* szName, ai_real iValue) -{ - bool existing; - ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue); - ASSIMP_END_EXCEPTION_REGION(bool); - return existing; -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool Importer::SetPropertyString(const char* szName, const std::string& value) -{ - bool existing; - ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value); - ASSIMP_END_EXCEPTION_REGION(bool); - return existing; -} - -// ------------------------------------------------------------------------------------------------ -// Set a configuration property -bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) -{ - bool existing; - ASSIMP_BEGIN_EXCEPTION_REGION(); - existing = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value); - ASSIMP_END_EXCEPTION_REGION(bool); - return existing; -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -int Importer::GetPropertyInteger(const char* szName, - int iErrorReturn /*= 0xffffffff*/) const -{ - return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -ai_real Importer::GetPropertyFloat(const char* szName, - ai_real iErrorReturn /*= 10e10*/) const -{ - return GetGenericProperty<ai_real>(pimpl->mFloatProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -const std::string Importer::GetPropertyString(const char* szName, - const std::string& iErrorReturn /*= ""*/) const -{ - return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Get a configuration property -const aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, - const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const -{ - return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn); -} - -// ------------------------------------------------------------------------------------------------ -// Get the memory requirements of a single node -inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode) -{ - iScene += sizeof(aiNode); - iScene += sizeof(unsigned int) * pcNode->mNumMeshes; - iScene += sizeof(void*) * pcNode->mNumChildren; - - for (unsigned int i = 0; i < pcNode->mNumChildren;++i) { - AddNodeWeight(iScene,pcNode->mChildren[i]); - } -} - -// ------------------------------------------------------------------------------------------------ -// Get the memory requirements of the scene -void Importer::GetMemoryRequirements(aiMemoryInfo& in) const -{ - in = aiMemoryInfo(); - aiScene* mScene = pimpl->mScene; - - // return if we have no scene loaded - if (!pimpl->mScene) - return; - - - in.total = sizeof(aiScene); - - // add all meshes - for (unsigned int i = 0; i < mScene->mNumMeshes;++i) - { - in.meshes += sizeof(aiMesh); - if (mScene->mMeshes[i]->HasPositions()) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; - } - - if (mScene->mMeshes[i]->HasNormals()) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; - } - - if (mScene->mMeshes[i]->HasTangentsAndBitangents()) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2; - } - - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) { - if (mScene->mMeshes[i]->HasVertexColors(a)) { - in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices; - } - else break; - } - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { - if (mScene->mMeshes[i]->HasTextureCoords(a)) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; - } - else break; - } - if (mScene->mMeshes[i]->HasBones()) { - in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones; - for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) { - in.meshes += sizeof(aiBone); - in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight); - } - } - in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces; - } - in.total += in.meshes; - - // add all embedded textures - for (unsigned int i = 0; i < mScene->mNumTextures;++i) { - const aiTexture* pc = mScene->mTextures[i]; - in.textures += sizeof(aiTexture); - if (pc->mHeight) { - in.textures += 4 * pc->mHeight * pc->mWidth; - } - else in.textures += pc->mWidth; - } - in.total += in.textures; - - // add all animations - for (unsigned int i = 0; i < mScene->mNumAnimations;++i) { - const aiAnimation* pc = mScene->mAnimations[i]; - in.animations += sizeof(aiAnimation); - - // add all bone anims - for (unsigned int a = 0; a < pc->mNumChannels; ++a) { - const aiNodeAnim* pc2 = pc->mChannels[i]; - in.animations += sizeof(aiNodeAnim); - in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey); - in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey); - in.animations += pc2->mNumRotationKeys * sizeof(aiQuatKey); - } - } - in.total += in.animations; - - // add all cameras and all lights - in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras; - in.total += in.lights = sizeof(aiLight) * mScene->mNumLights; - - // add all nodes - AddNodeWeight(in.nodes,mScene->mRootNode); - in.total += in.nodes; - - // add all materials - for (unsigned int i = 0; i < mScene->mNumMaterials;++i) { - const aiMaterial* pc = mScene->mMaterials[i]; - in.materials += sizeof(aiMaterial); - in.materials += pc->mNumAllocated * sizeof(void*); - - for (unsigned int a = 0; a < pc->mNumProperties;++a) { - in.materials += pc->mProperties[a]->mDataLength; - } - } - in.total += in.materials; -} diff --git a/thirdparty/assimp/code/Common/Importer.h b/thirdparty/assimp/code/Common/Importer.h deleted file mode 100644 index a439d99c2f..0000000000 --- a/thirdparty/assimp/code/Common/Importer.h +++ /dev/null @@ -1,247 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Importer.h mostly internal stuff for use by #Assimp::Importer */ -#pragma once -#ifndef INCLUDED_AI_IMPORTER_H -#define INCLUDED_AI_IMPORTER_H - -#include <map> -#include <vector> -#include <string> -#include <assimp/matrix4x4.h> - -struct aiScene; - -namespace Assimp { - class ProgressHandler; - class IOSystem; - class BaseImporter; - class BaseProcess; - class SharedPostProcessInfo; - - -//! @cond never -// --------------------------------------------------------------------------- -/** @brief Internal PIMPL implementation for Assimp::Importer - * - * Using this idiom here allows us to drop the dependency from - * std::vector and std::map in the public headers. Furthermore we are dropping - * any STL interface problems caused by mismatching STL settings. All - * size calculation are now done by us, not the app heap. */ -class ImporterPimpl { -public: - // Data type to store the key hash - typedef unsigned int KeyType; - - // typedefs for our four configuration maps. - // We don't need more, so there is no need for a generic solution - typedef std::map<KeyType, int> IntPropertyMap; - typedef std::map<KeyType, ai_real> FloatPropertyMap; - typedef std::map<KeyType, std::string> StringPropertyMap; - typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap; - - /** IO handler to use for all file accesses. */ - IOSystem* mIOHandler; - bool mIsDefaultHandler; - - /** Progress handler for feedback. */ - ProgressHandler* mProgressHandler; - bool mIsDefaultProgressHandler; - - /** Format-specific importer worker objects - one for each format we can read.*/ - std::vector< BaseImporter* > mImporter; - - /** Post processing steps we can apply at the imported data. */ - std::vector< BaseProcess* > mPostProcessingSteps; - - /** The imported data, if ReadFile() was successful, NULL otherwise. */ - aiScene* mScene; - - /** The error description, if there was one. */ - std::string mErrorString; - - /** List of integer properties */ - IntPropertyMap mIntProperties; - - /** List of floating-point properties */ - FloatPropertyMap mFloatProperties; - - /** List of string properties */ - StringPropertyMap mStringProperties; - - /** List of Matrix properties */ - MatrixPropertyMap mMatrixProperties; - - /** Used for testing - extra verbose mode causes the ValidateDataStructure-Step - * to be executed before and after every single post-process step */ - bool bExtraVerbose; - - /** Used by post-process steps to share data */ - SharedPostProcessInfo* mPPShared; - - /// The default class constructor. - ImporterPimpl() AI_NO_EXCEPT; -}; - -inline -ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT -: mIOHandler( nullptr ) -, mIsDefaultHandler( false ) -, mProgressHandler( nullptr ) -, mIsDefaultProgressHandler( false ) -, mImporter() -, mPostProcessingSteps() -, mScene( nullptr ) -, mErrorString() -, mIntProperties() -, mFloatProperties() -, mStringProperties() -, mMatrixProperties() -, bExtraVerbose( false ) -, mPPShared( nullptr ) { - // empty -} -//! @endcond - - -struct BatchData; - -// --------------------------------------------------------------------------- -/** FOR IMPORTER PLUGINS ONLY: A helper class to the pleasure of importers - * that need to load many external meshes recursively. - * - * The class uses several threads to load these meshes (or at least it - * could, this has not yet been implemented at the moment). - * - * @note The class may not be used by more than one thread*/ -class ASSIMP_API BatchLoader -{ - // friend of Importer - -public: - //! @cond never - // ------------------------------------------------------------------- - /** Wraps a full list of configuration properties for an importer. - * Properties can be set using SetGenericProperty */ - struct PropertyMap - { - ImporterPimpl::IntPropertyMap ints; - ImporterPimpl::FloatPropertyMap floats; - ImporterPimpl::StringPropertyMap strings; - ImporterPimpl::MatrixPropertyMap matrices; - - bool operator == (const PropertyMap& prop) const { - // fixme: really isocpp? gcc complains - return ints == prop.ints && floats == prop.floats && strings == prop.strings && matrices == prop.matrices; - } - - bool empty () const { - return ints.empty() && floats.empty() && strings.empty() && matrices.empty(); - } - }; - //! @endcond - -public: - // ------------------------------------------------------------------- - /** Construct a batch loader from a given IO system to be used - * to access external files - */ - explicit BatchLoader(IOSystem* pIO, bool validate = false ); - - // ------------------------------------------------------------------- - /** The class destructor. - */ - ~BatchLoader(); - - // ------------------------------------------------------------------- - /** Sets the validation step. True for enable validation during postprocess. - * @param enable True for validation. - */ - void setValidation( bool enabled ); - - // ------------------------------------------------------------------- - /** Returns the current validation step. - * @return The current validation step. - */ - bool getValidation() const; - - // ------------------------------------------------------------------- - /** Add a new file to the list of files to be loaded. - * @param file File to be loaded - * @param steps Post-processing steps to be executed on the file - * @param map Optional configuration properties - * @return 'Load request channel' - an unique ID that can later - * be used to access the imported file data. - * @see GetImport */ - unsigned int AddLoadRequest ( - const std::string& file, - unsigned int steps = 0, - const PropertyMap* map = NULL - ); - - // ------------------------------------------------------------------- - /** Get an imported scene. - * This polls the import from the internal request list. - * If an import is requested several times, this function - * can be called several times, too. - * - * @param which LRWC returned by AddLoadRequest(). - * @return NULL if there is no scene with this file name - * in the queue of the scene hasn't been loaded yet. */ - aiScene* GetImport( - unsigned int which - ); - - // ------------------------------------------------------------------- - /** Waits until all scenes have been loaded. This returns - * immediately if no scenes are queued.*/ - void LoadAll(); - -private: - // No need to have that in the public API ... - BatchData *m_data; -}; - -} // Namespace Assimp - -#endif // INCLUDED_AI_IMPORTER_H diff --git a/thirdparty/assimp/code/Common/ImporterRegistry.cpp b/thirdparty/assimp/code/Common/ImporterRegistry.cpp deleted file mode 100644 index b9f28f0356..0000000000 --- a/thirdparty/assimp/code/Common/ImporterRegistry.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file ImporterRegistry.cpp - -Central registry for all importers available. Do not edit this file -directly (unless you are adding new loaders), instead use the -corresponding preprocessor flag to selectively disable formats. -*/ - -#include <vector> -#include <assimp/BaseImporter.h> - -// ------------------------------------------------------------------------------------------------ -// Importers -// (include_new_importers_here) -// ------------------------------------------------------------------------------------------------ -#ifndef ASSIMP_BUILD_NO_X_IMPORTER -# include "X/XFileImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER -# include "AMF/AMFImporter.hpp" -#endif -#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER -# include "3DS/3DSLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER -# include "MD3/MD3Loader.h" -#endif -#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER -# include "MDL/MDLLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER -# include "MD2/MD2Loader.h" -#endif -#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER -# include "Ply/PlyLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER -# include "ASE/ASELoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER -# include "Obj/ObjFileImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER -# include "HMP/HMPLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER -# include "SMD/SMDLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER -# include "MDC/MDCLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER -# include "MD5/MD5Loader.h" -#endif -#ifndef ASSIMP_BUILD_NO_STL_IMPORTER -# include "STL/STLLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER -# include "LWO/LWOLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER -# include "DXF/DXFLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER -# include "NFF/NFFLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER -# include "Raw/RawLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER -# include "SIB/SIBImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER -# include "OFF/OFFLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_AC_IMPORTER -# include "AC/ACLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER -# include "BVH/BVHLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER -# include "Irr/IRRMeshLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER -# include "Irr/IRRLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER -# include "Q3D/Q3DLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER -# include "B3D/B3DImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER -# include "Collada/ColladaLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER -# include "Terragen/TerragenLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER -# include "CSM/CSMLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_3D_IMPORTER -# include "Unreal/UnrealLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER -# include "LWS/LWSLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER -# include "Ogre/OgreImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER -# include "OpenGEX/OpenGEXImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER -# include "MS3D/MS3DLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_COB_IMPORTER -# include "COB/COBLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER -# include "Blender/BlenderLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER -# include "Q3BSP/Q3BSPFileImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER -# include "NDO/NDOLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER -# include "Importer/IFC/IFCLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER -# include "XGL/XGLLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER -# include "FBX/FBXImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER -# include "Assbin/AssbinLoader.h" -#endif -#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER -# include "glTF/glTFImporter.h" -# include "glTF2/glTF2Importer.h" -#endif -#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER -# include "C4D/C4DImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER -# include "3MF/D3MFImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER -# include "X3D/X3DImporter.hpp" -#endif -#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER -# include "MMD/MMDImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER -# include "M3D/M3DImporter.h" -#endif -#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER -# include "Importer/StepFile/StepFileImporter.h" -#endif - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -void GetImporterInstanceList(std::vector< BaseImporter* >& out) -{ - // ---------------------------------------------------------------------------- - // Add an instance of each worker class here - // (register_new_importers_here) - // ---------------------------------------------------------------------------- - out.reserve(64); -#if (!defined ASSIMP_BUILD_NO_X_IMPORTER) - out.push_back( new XFileImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER) - out.push_back( new ObjFileImporter()); -#endif -#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER - out.push_back( new AMFImporter() ); -#endif -#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER) - out.push_back( new Discreet3DSImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_M3D_IMPORTER) - out.push_back( new M3DImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER) - out.push_back( new MD3Importer()); -#endif -#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER) - out.push_back( new MD2Importer()); -#endif -#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER) - out.push_back( new PLYImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER) - out.push_back( new MDLImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER) - #if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER) - out.push_back( new ASEImporter()); -# endif -#endif -#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER) - out.push_back( new HMPImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER) - out.push_back( new SMDImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER) - out.push_back( new MDCImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER) - out.push_back( new MD5Importer()); -#endif -#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER) - out.push_back( new STLImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) - out.push_back( new LWOImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER) - out.push_back( new DXFImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER) - out.push_back( new NFFImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER) - out.push_back( new RAWImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_SIB_IMPORTER) - out.push_back( new SIBImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER) - out.push_back( new OFFImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER) - out.push_back( new AC3DImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER) - out.push_back( new BVHLoader()); -#endif -#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER) - out.push_back( new IRRMeshImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER) - out.push_back( new IRRImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER) - out.push_back( new Q3DImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER) - out.push_back( new B3DImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER) - out.push_back( new ColladaLoader()); -#endif -#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER) - out.push_back( new TerragenImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER) - out.push_back( new CSMImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER) - out.push_back( new UnrealImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER) - out.push_back( new LWSImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER) - out.push_back( new Ogre::OgreImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_OPENGEX_IMPORTER ) - out.push_back( new OpenGEX::OpenGEXImporter() ); -#endif -#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER) - out.push_back( new MS3DImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER) - out.push_back( new COBImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER) - out.push_back( new BlenderImporter()); -#endif -#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER) - out.push_back( new Q3BSPFileImporter() ); -#endif -#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER) - out.push_back( new NDOImporter() ); -#endif -#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER) - out.push_back( new IFCImporter() ); -#endif -#if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER ) - out.push_back( new XGLImporter() ); -#endif -#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) - out.push_back( new FBXImporter() ); -#endif -#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER ) - out.push_back( new AssbinImporter() ); -#endif -#if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER ) - out.push_back( new glTFImporter() ); - out.push_back( new glTF2Importer() ); -#endif -#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER ) - out.push_back( new C4DImporter() ); -#endif -#if ( !defined ASSIMP_BUILD_NO_3MF_IMPORTER ) - out.push_back( new D3MFImporter() ); -#endif -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - out.push_back( new X3DImporter() ); -#endif -#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER - out.push_back( new MMDImporter() ); -#endif -#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER - out.push_back(new StepFile::StepFileImporter()); -#endif -} - -/** will delete all registered importers. */ -void DeleteImporterInstanceList(std::vector< BaseImporter* >& deleteList){ - for(size_t i= 0; i<deleteList.size();++i){ - delete deleteList[i]; - deleteList[i]=nullptr; - }//for -} - -} // namespace Assimp diff --git a/thirdparty/assimp/code/Common/PolyTools.h b/thirdparty/assimp/code/Common/PolyTools.h deleted file mode 100644 index fbbda0e7d1..0000000000 --- a/thirdparty/assimp/code/Common/PolyTools.h +++ /dev/null @@ -1,229 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file PolyTools.h, various utilities for our dealings with arbitrary polygons */ - -#ifndef AI_POLYTOOLS_H_INCLUDED -#define AI_POLYTOOLS_H_INCLUDED - -#include <assimp/material.h> -#include <assimp/ai_assert.h> - -namespace Assimp { - -// ------------------------------------------------------------------------------- -/** Compute the signed area of a triangle. - * The function accepts an unconstrained template parameter for use with - * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/ -template <typename T> -inline double GetArea2D(const T& v1, const T& v2, const T& v3) -{ - return 0.5 * (v1.x * ((double)v3.y - v2.y) + v2.x * ((double)v1.y - v3.y) + v3.x * ((double)v2.y - v1.y)); -} - -// ------------------------------------------------------------------------------- -/** Test if a given point p2 is on the left side of the line formed by p0-p1. - * The function accepts an unconstrained template parameter for use with - * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/ -template <typename T> -inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) -{ - return GetArea2D(p0,p2,p1) > 0; -} - -// ------------------------------------------------------------------------------- -/** Test if a given point is inside a given triangle in R2. - * The function accepts an unconstrained template parameter for use with - * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/ -template <typename T> -inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) -{ - // Point in triangle test using baryzentric coordinates - const aiVector2D v0 = p1 - p0; - const aiVector2D v1 = p2 - p0; - const aiVector2D v2 = pp - p0; - - double dot00 = v0 * v0; - double dot01 = v0 * v1; - double dot02 = v0 * v2; - double dot11 = v1 * v1; - double dot12 = v1 * v2; - - const double invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom; - dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom; - - return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1); -} - - -// ------------------------------------------------------------------------------- -/** Check whether the winding order of a given polygon is counter-clockwise. - * The function accepts an unconstrained template parameter, but is intended - * to be used only with aiVector2D and aiVector3D (z axis is ignored, only - * x and y are taken into account). - * @note Code taken from http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/applet1.html and translated to C++ - */ -template <typename T> -inline bool IsCCW(T* in, size_t npoints) { - double aa, bb, cc, b, c, theta; - double convex_turn; - double convex_sum = 0; - - ai_assert(npoints >= 3); - - for (size_t i = 0; i < npoints - 2; i++) { - aa = ((in[i+2].x - in[i].x) * (in[i+2].x - in[i].x)) + - ((-in[i+2].y + in[i].y) * (-in[i+2].y + in[i].y)); - - bb = ((in[i+1].x - in[i].x) * (in[i+1].x - in[i].x)) + - ((-in[i+1].y + in[i].y) * (-in[i+1].y + in[i].y)); - - cc = ((in[i+2].x - in[i+1].x) * - (in[i+2].x - in[i+1].x)) + - ((-in[i+2].y + in[i+1].y) * - (-in[i+2].y + in[i+1].y)); - - b = std::sqrt(bb); - c = std::sqrt(cc); - theta = std::acos((bb + cc - aa) / (2 * b * c)); - - if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1])) { - // if (convex(in[i].x, in[i].y, - // in[i+1].x, in[i+1].y, - // in[i+2].x, in[i+2].y)) { - convex_turn = AI_MATH_PI_F - theta; - convex_sum += convex_turn; - } - else { - convex_sum -= AI_MATH_PI_F - theta; - } - } - aa = ((in[1].x - in[npoints-2].x) * - (in[1].x - in[npoints-2].x)) + - ((-in[1].y + in[npoints-2].y) * - (-in[1].y + in[npoints-2].y)); - - bb = ((in[0].x - in[npoints-2].x) * - (in[0].x - in[npoints-2].x)) + - ((-in[0].y + in[npoints-2].y) * - (-in[0].y + in[npoints-2].y)); - - cc = ((in[1].x - in[0].x) * (in[1].x - in[0].x)) + - ((-in[1].y + in[0].y) * (-in[1].y + in[0].y)); - - b = std::sqrt(bb); - c = std::sqrt(cc); - theta = std::acos((bb + cc - aa) / (2 * b * c)); - - //if (convex(in[npoints-2].x, in[npoints-2].y, - // in[0].x, in[0].y, - // in[1].x, in[1].y)) { - if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0])) { - convex_turn = AI_MATH_PI_F - theta; - convex_sum += convex_turn; - } - else { - convex_sum -= AI_MATH_PI_F - theta; - } - - return convex_sum >= (2 * AI_MATH_PI_F); -} - - -// ------------------------------------------------------------------------------- -/** Compute the normal of an arbitrary polygon in R3. - * - * The code is based on Newell's formula, that is a polygons normal is the ratio - * of its area when projected onto the three coordinate axes. - * - * @param out Receives the output normal - * @param num Number of input vertices - * @param x X data source. x[ofs_x*n] is the n'th element. - * @param y Y data source. y[ofs_y*n] is the y'th element - * @param z Z data source. z[ofs_z*n] is the z'th element - * - * @note The data arrays must have storage for at least num+2 elements. Using - * this method is much faster than the 'other' NewellNormal() - */ -template <int ofs_x, int ofs_y, int ofs_z, typename TReal> -inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, TReal* z) -{ - // Duplicate the first two vertices at the end - x[(num+0)*ofs_x] = x[0]; - x[(num+1)*ofs_x] = x[ofs_x]; - - y[(num+0)*ofs_y] = y[0]; - y[(num+1)*ofs_y] = y[ofs_y]; - - z[(num+0)*ofs_z] = z[0]; - z[(num+1)*ofs_z] = z[ofs_z]; - - TReal sum_xy = 0.0, sum_yz = 0.0, sum_zx = 0.0; - - TReal *xptr = x +ofs_x, *xlow = x, *xhigh = x + ofs_x*2; - TReal *yptr = y +ofs_y, *ylow = y, *yhigh = y + ofs_y*2; - TReal *zptr = z +ofs_z, *zlow = z, *zhigh = z + ofs_z*2; - - for (int tmp=0; tmp < num; tmp++) { - sum_xy += (*xptr) * ( (*yhigh) - (*ylow) ); - sum_yz += (*yptr) * ( (*zhigh) - (*zlow) ); - sum_zx += (*zptr) * ( (*xhigh) - (*xlow) ); - - xptr += ofs_x; - xlow += ofs_x; - xhigh += ofs_x; - - yptr += ofs_y; - ylow += ofs_y; - yhigh += ofs_y; - - zptr += ofs_z; - zlow += ofs_z; - zhigh += ofs_z; - } - out = aiVector3t<TReal>(sum_yz,sum_zx,sum_xy); -} - -} // ! Assimp - -#endif diff --git a/thirdparty/assimp/code/Common/PostStepRegistry.cpp b/thirdparty/assimp/code/Common/PostStepRegistry.cpp deleted file mode 100644 index 8ff4af0400..0000000000 --- a/thirdparty/assimp/code/Common/PostStepRegistry.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file ImporterRegistry.cpp - -Central registry for all postprocessing steps available. Do not edit this file -directly (unless you are adding new steps), instead use the -corresponding preprocessor flag to selectively disable steps. -*/ - -#include "PostProcessing/ProcessHelper.h" - -#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS -# include "PostProcessing/CalcTangentsProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS -# include "PostProcessing/JoinVerticesProcess.h" -#endif -#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS) -# include "PostProcessing/ConvertToLHProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS -# include "PostProcessing/TriangulateProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_DROPFACENORMALS_PROCESS -# include "PostProcessing/DropFaceNormalsProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS -# include "PostProcessing/GenFaceNormalsProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS -# include "PostProcessing/GenVertexNormalsProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS -# include "PostProcessing/RemoveVCProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS -# include "PostProcessing/SplitLargeMeshes.h" -#endif -#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS -# include "PostProcessing/PretransformVertices.h" -#endif -#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS -# include "PostProcessing/LimitBoneWeightsProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS -# include "PostProcessing/ValidateDataStructure.h" -#endif -#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS -# include "PostProcessing/ImproveCacheLocality.h" -#endif -#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS -# include "PostProcessing/FixNormalsStep.h" -#endif -#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS -# include "PostProcessing/RemoveRedundantMaterials.h" -#endif -#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS) -# include "PostProcessing/EmbedTexturesProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS -# include "PostProcessing/FindInvalidDataProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS -# include "PostProcessing/FindDegenerates.h" -#endif -#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS -# include "PostProcessing/SortByPTypeProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS -# include "PostProcessing/ComputeUVMappingProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS -# include "PostProcessing/TextureTransform.h" -#endif -#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS -# include "PostProcessing/FindInstancesProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS -# include "PostProcessing/OptimizeMeshes.h" -#endif -#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS -# include "PostProcessing/OptimizeGraph.h" -#endif -#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS -# include "Common/SplitByBoneCountProcess.h" -#endif -#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS -# include "PostProcessing/DeboneProcess.h" -#endif -#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS) -# include "PostProcessing/ScaleProcess.h" -#endif -#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS) -# include "PostProcessing/ArmaturePopulate.h" -#endif -#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS) -# include "PostProcessing/GenBoundingBoxesProcess.h" -#endif - - - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) -{ - // ---------------------------------------------------------------------------- - // Add an instance of each post processing step here in the order - // of sequence it is executed. Steps that are added here are not - // validated - as RegisterPPStep() does - all dependencies must be given. - // ---------------------------------------------------------------------------- - out.reserve(31); -#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS) - out.push_back( new MakeLeftHandedProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS) - out.push_back( new FlipUVsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS) - out.push_back( new FlipWindingOrderProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS) - out.push_back( new RemoveVCProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS) - out.push_back( new RemoveRedundantMatsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS) - out.push_back( new EmbedTexturesProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS) - out.push_back( new FindInstancesProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS) - out.push_back( new OptimizeGraphProcess()); -#endif -#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS - out.push_back( new ComputeUVMappingProcess()); -#endif -#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS - out.push_back( new TextureTransformStep()); -#endif -#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS) - out.push_back( new ScaleProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS) - out.push_back( new ArmaturePopulate()); -#endif -#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS) - out.push_back( new PretransformVertices()); -#endif -#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS) - out.push_back( new TriangulateProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS) - //find degenerates should run after triangulation (to sort out small - //generated triangles) but before sort by p types (in case there are lines - //and points generated and inserted into a mesh) - out.push_back( new FindDegeneratesProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS) - out.push_back( new SortByPTypeProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS) - out.push_back( new FindInvalidDataProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS) - out.push_back( new OptimizeMeshesProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS) - out.push_back( new FixInfacingNormalsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS) - out.push_back( new SplitByBoneCountProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS) - out.push_back( new SplitLargeMeshesProcess_Triangle()); -#endif -#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS) - out.push_back( new DropFaceNormalsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS) - out.push_back( new GenFaceNormalsProcess()); -#endif - // ......................................................................... - // DON'T change the order of these five .. - // XXX this is actually a design weakness that dates back to the time - // when Importer would maintain the postprocessing step list exclusively. - // Now that others access it too, we need a better solution. - out.push_back( new ComputeSpatialSortProcess()); - // ......................................................................... - -#if (!defined ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS) - out.push_back( new GenVertexNormalsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS) - out.push_back( new CalcTangentsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_JOINVERTICES_PROCESS) - out.push_back( new JoinVerticesProcess()); -#endif - - // ......................................................................... - out.push_back( new DestroySpatialSortProcess()); - // ......................................................................... - -#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS) - out.push_back( new SplitLargeMeshesProcess_Vertex()); -#endif -#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS) - out.push_back( new DeboneProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS) - out.push_back( new LimitBoneWeightsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS) - out.push_back( new ImproveCacheLocalityProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS) - out.push_back(new GenBoundingBoxesProcess); -#endif -} - -} diff --git a/thirdparty/assimp/code/Common/RemoveComments.cpp b/thirdparty/assimp/code/Common/RemoveComments.cpp deleted file mode 100644 index 91700a7699..0000000000 --- a/thirdparty/assimp/code/Common/RemoveComments.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file RemoveComments.cpp - * @brief Defines the CommentRemover utility class - */ - -#include <assimp/RemoveComments.h> -#include <assimp/ParsingUtils.h> - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -// Remove line comments from a file -void CommentRemover::RemoveLineComments(const char* szComment, - char* szBuffer, char chReplacement /* = ' ' */) -{ - // validate parameters - ai_assert(NULL != szComment && NULL != szBuffer && *szComment); - - const size_t len = strlen(szComment); - while (*szBuffer) { - - // skip over quotes - if (*szBuffer == '\"' || *szBuffer == '\'') - while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\''); - - if (!strncmp(szBuffer,szComment,len)) { - while (!IsLineEnd(*szBuffer)) - *szBuffer++ = chReplacement; - - if (!*szBuffer) { - break; - } - } - ++szBuffer; - } -} - -// ------------------------------------------------------------------------------------------------ -// Remove multi-line comments from a file -void CommentRemover::RemoveMultiLineComments(const char* szCommentStart, - const char* szCommentEnd,char* szBuffer, - char chReplacement) -{ - // validate parameters - ai_assert(NULL != szCommentStart && NULL != szCommentEnd && - NULL != szBuffer && *szCommentStart && *szCommentEnd); - - const size_t len = strlen(szCommentEnd); - const size_t len2 = strlen(szCommentStart); - - while (*szBuffer) { - // skip over quotes - if (*szBuffer == '\"' || *szBuffer == '\'') - while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\''); - - if (!strncmp(szBuffer,szCommentStart,len2)) { - while (*szBuffer) { - if (!::strncmp(szBuffer,szCommentEnd,len)) { - for (unsigned int i = 0; i < len;++i) - *szBuffer++ = chReplacement; - - break; - } - *szBuffer++ = chReplacement; - } - continue; - } - ++szBuffer; - } -} - -} // !! Assimp diff --git a/thirdparty/assimp/code/Common/SGSpatialSort.cpp b/thirdparty/assimp/code/Common/SGSpatialSort.cpp deleted file mode 100644 index 120070b0aa..0000000000 --- a/thirdparty/assimp/code/Common/SGSpatialSort.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the helper class to quickly find -vertices close to a given position. Special implementation for -the 3ds loader handling smooth groups correctly */ - -#include <assimp/SGSpatialSort.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -SGSpatialSort::SGSpatialSort() -{ - // define the reference plane. We choose some arbitrary vector away from all basic axises - // in the hope that no model spreads all its vertices along this plane. - mPlaneNormal.Set( 0.8523f, 0.34321f, 0.5736f); - mPlaneNormal.Normalize(); -} -// ------------------------------------------------------------------------------------------------ -// Destructor -SGSpatialSort::~SGSpatialSort() -{ - // nothing to do here, everything destructs automatically -} -// ------------------------------------------------------------------------------------------------ -void SGSpatialSort::Add(const aiVector3D& vPosition, unsigned int index, - unsigned int smoothingGroup) -{ - // store position by index and distance - float distance = vPosition * mPlaneNormal; - mPositions.push_back( Entry( index, vPosition, - distance, smoothingGroup)); -} -// ------------------------------------------------------------------------------------------------ -void SGSpatialSort::Prepare() -{ - // now sort the array ascending by distance. - std::sort( this->mPositions.begin(), this->mPositions.end()); -} -// ------------------------------------------------------------------------------------------------ -// Returns an iterator for all positions close to the given position. -void SGSpatialSort::FindPositions( const aiVector3D& pPosition, - uint32_t pSG, - float pRadius, - std::vector<unsigned int>& poResults, - bool exactMatch /*= false*/) const -{ - float dist = pPosition * mPlaneNormal; - float minDist = dist - pRadius, maxDist = dist + pRadius; - - // clear the array - poResults.clear(); - - // quick check for positions outside the range - if( mPositions.empty() ) - return; - if( maxDist < mPositions.front().mDistance) - return; - if( minDist > mPositions.back().mDistance) - return; - - // do a binary search for the minimal distance to start the iteration there - unsigned int index = (unsigned int)mPositions.size() / 2; - unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4; - while( binaryStepSize > 1) - { - if( mPositions[index].mDistance < minDist) - index += binaryStepSize; - else - index -= binaryStepSize; - - binaryStepSize /= 2; - } - - // depending on the direction of the last step we need to single step a bit back or forth - // to find the actual beginning element of the range - while( index > 0 && mPositions[index].mDistance > minDist) - index--; - while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist) - index++; - - // Mow start iterating from there until the first position lays outside of the distance range. - // Add all positions inside the distance range within the given radius to the result aray - - float squareEpsilon = pRadius * pRadius; - std::vector<Entry>::const_iterator it = mPositions.begin() + index; - std::vector<Entry>::const_iterator end = mPositions.end(); - - if (exactMatch) - { - while( it->mDistance < maxDist) - { - if((it->mPosition - pPosition).SquareLength() < squareEpsilon && it->mSmoothGroups == pSG) - { - poResults.push_back( it->mIndex); - } - ++it; - if( end == it )break; - } - } - else - { - // if the given smoothing group is 0, we'll return all surrounding vertices - if (!pSG) - { - while( it->mDistance < maxDist) - { - if((it->mPosition - pPosition).SquareLength() < squareEpsilon) - poResults.push_back( it->mIndex); - ++it; - if( end == it)break; - } - } - else while( it->mDistance < maxDist) - { - if((it->mPosition - pPosition).SquareLength() < squareEpsilon && - (it->mSmoothGroups & pSG || !it->mSmoothGroups)) - { - poResults.push_back( it->mIndex); - } - ++it; - if( end == it)break; - } - } -} - - diff --git a/thirdparty/assimp/code/Common/SceneCombiner.cpp b/thirdparty/assimp/code/Common/SceneCombiner.cpp deleted file mode 100644 index f7b13cc951..0000000000 --- a/thirdparty/assimp/code/Common/SceneCombiner.cpp +++ /dev/null @@ -1,1350 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -// TODO: refactor entire file to get rid of the "flat-copy" first approach -// to copying structures. This easily breaks in the most unintuitive way -// possible as new fields are added to assimp structures. - -// ---------------------------------------------------------------------------- -/** - * @file Implements Assimp::SceneCombiner. This is a smart utility - * class that combines multiple scenes, meshes, ... into one. Currently - * these utilities are used by the IRR and LWS loaders and the - * OptimizeGraph step. - */ -// ---------------------------------------------------------------------------- -#include <assimp/SceneCombiner.h> -#include <assimp/StringUtils.h> -#include <assimp/fast_atof.h> -#include <assimp/metadata.h> -#include <assimp/Hash.h> -#include "time.h" -#include <assimp/DefaultLogger.hpp> -#include <assimp/scene.h> -#include <assimp/mesh.h> -#include <stdio.h> -#include "ScenePrivate.h" - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -// Add a prefix to a string -inline -void PrefixString(aiString& string,const char* prefix, unsigned int len) { - // If the string is already prefixed, we won't prefix it a second time - if (string.length >= 1 && string.data[0] == '$') - return; - - if (len+string.length>=MAXLEN-1) { - ASSIMP_LOG_DEBUG("Can't add an unique prefix because the string is too long"); - ai_assert(false); - return; - } - - // Add the prefix - ::memmove(string.data+len,string.data,string.length+1); - ::memcpy (string.data, prefix, len); - - // And update the string's length - string.length += len; -} - -// ------------------------------------------------------------------------------------------------ -// Add node identifiers to a hashing set -void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes) { - // Add node name to hashing set if it is non-empty - empty nodes are allowed - // and they can't have any anims assigned so its absolutely safe to duplicate them. - if (node->mName.length) { - hashes.insert( SuperFastHash(node->mName.data, static_cast<uint32_t>(node->mName.length)) ); - } - - // Process all children recursively - for (unsigned int i = 0; i < node->mNumChildren;++i) - AddNodeHashes(node->mChildren[i],hashes); -} - -// ------------------------------------------------------------------------------------------------ -// Add a name prefix to all nodes in a hierarchy -void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len) { - ai_assert(NULL != prefix); - PrefixString(node->mName,prefix,len); - - // Process all children recursively - for ( unsigned int i = 0; i < node->mNumChildren; ++i ) { - AddNodePrefixes( node->mChildren[ i ], prefix, len ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Search for matching names -bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>& input, unsigned int cur) { - const unsigned int hash = SuperFastHash(name.data, static_cast<uint32_t>(name.length)); - - // Check whether we find a positive match in one of the given sets - for (unsigned int i = 0; i < input.size(); ++i) { - if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) { - return true; - } - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Add a name prefix to all nodes in a hierarchy if a hash match is found -void SceneCombiner::AddNodePrefixesChecked(aiNode* node, const char* prefix, unsigned int len, - std::vector<SceneHelper>& input, unsigned int cur) { - ai_assert(NULL != prefix); - const unsigned int hash = SuperFastHash(node->mName.data, static_cast<uint32_t>(node->mName.length)); - - // Check whether we find a positive match in one of the given sets - for (unsigned int i = 0; i < input.size(); ++i) { - if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) { - PrefixString(node->mName,prefix,len); - break; - } - } - - // Process all children recursively - for (unsigned int i = 0; i < node->mNumChildren;++i) - AddNodePrefixesChecked(node->mChildren[i],prefix,len,input,cur); -} - -// ------------------------------------------------------------------------------------------------ -// Add an offset to all mesh indices in a node graph -void SceneCombiner::OffsetNodeMeshIndices (aiNode* node, unsigned int offset) { - for (unsigned int i = 0; i < node->mNumMeshes;++i) - node->mMeshes[i] += offset; - - for ( unsigned int i = 0; i < node->mNumChildren; ++i ) { - OffsetNodeMeshIndices( node->mChildren[ i ], offset ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Merges two scenes. Currently only used by the LWS loader. -void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src, unsigned int flags) { - if ( nullptr == _dest ) { - return; - } - - // if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it - if (src.empty()) { - if (*_dest) { - (*_dest)->~aiScene(); - SceneCombiner::CopySceneFlat(_dest,src[0]); - } - else *_dest = src[0]; - return; - } - if (*_dest)(*_dest)->~aiScene(); - else *_dest = new aiScene(); - - // Create a dummy scene to serve as master for the others - aiScene* master = new aiScene(); - master->mRootNode = new aiNode(); - master->mRootNode->mName.Set("<MergeRoot>"); - - std::vector<AttachmentInfo> srcList (src.size()); - for (unsigned int i = 0; i < srcList.size();++i) { - srcList[i] = AttachmentInfo(src[i],master->mRootNode); - } - - // 'master' will be deleted afterwards - MergeScenes (_dest, master, srcList, flags); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList) { - unsigned int cnt; - for ( cnt = 0; cnt < attach->mNumChildren; ++cnt ) { - AttachToGraph( attach->mChildren[ cnt ], srcList ); - } - - cnt = 0; - for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin(); - it != srcList.end(); ++it) - { - if ((*it).attachToNode == attach && !(*it).resolved) - ++cnt; - } - - if (cnt) { - aiNode** n = new aiNode*[cnt+attach->mNumChildren]; - if (attach->mNumChildren) { - ::memcpy(n,attach->mChildren,sizeof(void*)*attach->mNumChildren); - delete[] attach->mChildren; - } - attach->mChildren = n; - - n += attach->mNumChildren; - attach->mNumChildren += cnt; - - for (unsigned int i = 0; i < srcList.size();++i) { - NodeAttachmentInfo& att = srcList[i]; - if (att.attachToNode == attach && !att.resolved) { - *n = att.node; - (**n).mParent = attach; - ++n; - - // mark this attachment as resolved - att.resolved = true; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::AttachToGraph ( aiScene* master, std::vector<NodeAttachmentInfo>& src) { - ai_assert(NULL != master); - AttachToGraph(master->mRootNode,src); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master, std::vector<AttachmentInfo>& srcList, unsigned int flags) { - if ( nullptr == _dest ) { - return; - } - - // if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it - if (srcList.empty()) { - if (*_dest) { - SceneCombiner::CopySceneFlat(_dest,master); - } - else *_dest = master; - return; - } - if (*_dest) { - (*_dest)->~aiScene(); - new (*_dest) aiScene(); - } - else *_dest = new aiScene(); - - aiScene* dest = *_dest; - - std::vector<SceneHelper> src (srcList.size()+1); - src[0].scene = master; - for (unsigned int i = 0; i < srcList.size();++i) { - src[i+1] = SceneHelper( srcList[i].scene ); - } - - // this helper array specifies which scenes are duplicates of others - std::vector<unsigned int> duplicates(src.size(),UINT_MAX); - - // this helper array is used as lookup table several times - std::vector<unsigned int> offset(src.size()); - - // Find duplicate scenes - for (unsigned int i = 0; i < src.size();++i) { - if (duplicates[i] != i && duplicates[i] != UINT_MAX) { - continue; - } - - duplicates[i] = i; - for ( unsigned int a = i+1; a < src.size(); ++a) { - if (src[i].scene == src[a].scene) { - duplicates[a] = i; - } - } - } - - // Generate unique names for all named stuff? - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) - { -#if 0 - // Construct a proper random number generator - boost::mt19937 rng( ); - boost::uniform_int<> dist(1u,1 << 24u); - boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rndGen(rng, dist); -#endif - for (unsigned int i = 1; i < src.size();++i) - { - //if (i != duplicates[i]) - //{ - // // duplicate scenes share the same UID - // ::strcpy( src[i].id, src[duplicates[i]].id ); - // src[i].idlen = src[duplicates[i]].idlen; - - // continue; - //} - - src[i].idlen = ai_snprintf(src[i].id, 32, "$%.6X$_",i); - - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - - // Compute hashes for all identifiers in this scene and store them - // in a sorted table (for convenience I'm using std::set). We hash - // just the node and animation channel names, all identifiers except - // the material names should be caught by doing this. - AddNodeHashes(src[i]->mRootNode,src[i].hashes); - - for (unsigned int a = 0; a < src[i]->mNumAnimations;++a) { - aiAnimation* anim = src[i]->mAnimations[a]; - src[i].hashes.insert(SuperFastHash(anim->mName.data,static_cast<uint32_t>(anim->mName.length))); - } - } - } - } - - unsigned int cnt; - - // First find out how large the respective output arrays must be - for ( unsigned int n = 0; n < src.size();++n ) - { - SceneHelper* cur = &src[n]; - - if (n == duplicates[n] || flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) { - dest->mNumTextures += (*cur)->mNumTextures; - dest->mNumMaterials += (*cur)->mNumMaterials; - dest->mNumMeshes += (*cur)->mNumMeshes; - } - - dest->mNumLights += (*cur)->mNumLights; - dest->mNumCameras += (*cur)->mNumCameras; - dest->mNumAnimations += (*cur)->mNumAnimations; - - // Combine the flags of all scenes - // We need to process them flag-by-flag here to get correct results - // dest->mFlags ; //|= (*cur)->mFlags; - if ((*cur)->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { - dest->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; - } - } - - // generate the output texture list + an offset table for all texture indices - if (dest->mNumTextures) - { - aiTexture** pip = dest->mTextures = new aiTexture*[dest->mNumMaterials]; - cnt = 0; - for ( unsigned int n = 0; n < src.size();++n ) - { - SceneHelper* cur = &src[n]; - for (unsigned int i = 0; i < (*cur)->mNumTextures;++i) - { - if (n != duplicates[n]) - { - if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) - Copy(pip,(*cur)->mTextures[i]); - - else continue; - } - else *pip = (*cur)->mTextures[i]; - ++pip; - } - - offset[n] = cnt; - cnt = (unsigned int)(pip - dest->mTextures); - } - } - - // generate the output material list + an offset table for all material indices - if (dest->mNumMaterials) - { - aiMaterial** pip = dest->mMaterials = new aiMaterial*[dest->mNumMaterials]; - cnt = 0; - for ( unsigned int n = 0; n < src.size();++n ) { - SceneHelper* cur = &src[n]; - for (unsigned int i = 0; i < (*cur)->mNumMaterials;++i) - { - if (n != duplicates[n]) - { - if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) - Copy(pip,(*cur)->mMaterials[i]); - - else continue; - } - else *pip = (*cur)->mMaterials[i]; - - if ((*cur)->mNumTextures != dest->mNumTextures) { - // We need to update all texture indices of the mesh. So we need to search for - // a material property called '$tex.file' - - for (unsigned int a = 0; a < (*pip)->mNumProperties;++a) - { - aiMaterialProperty* prop = (*pip)->mProperties[a]; - if (!strncmp(prop->mKey.data,"$tex.file",9)) - { - // Check whether this texture is an embedded texture. - // In this case the property looks like this: *<n>, - // where n is the index of the texture. - aiString& s = *((aiString*)prop->mData); - if ('*' == s.data[0]) { - // Offset the index and write it back .. - const unsigned int idx = strtoul10(&s.data[1]) + offset[n]; - ASSIMP_itoa10(&s.data[1],sizeof(s.data)-1,idx); - } - } - - // Need to generate new, unique material names? - else if (!::strcmp( prop->mKey.data,"$mat.name" ) && flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) - { - aiString* pcSrc = (aiString*) prop->mData; - PrefixString(*pcSrc, (*cur).id, (*cur).idlen); - } - } - } - ++pip; - } - - offset[n] = cnt; - cnt = (unsigned int)(pip - dest->mMaterials); - } - } - - // generate the output mesh list + again an offset table for all mesh indices - if (dest->mNumMeshes) - { - aiMesh** pip = dest->mMeshes = new aiMesh*[dest->mNumMeshes]; - cnt = 0; - for ( unsigned int n = 0; n < src.size();++n ) - { - SceneHelper* cur = &src[n]; - for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i) - { - if (n != duplicates[n]) { - if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) - Copy(pip, (*cur)->mMeshes[i]); - - else continue; - } - else *pip = (*cur)->mMeshes[i]; - - // update the material index of the mesh - (*pip)->mMaterialIndex += offset[n]; - ++pip; - } - - // reuse the offset array - store now the mesh offset in it - offset[n] = cnt; - cnt = (unsigned int)(pip - dest->mMeshes); - } - } - - std::vector <NodeAttachmentInfo> nodes; - nodes.reserve(srcList.size()); - - // ---------------------------------------------------------------------------- - // Now generate the output node graph. We need to make those - // names in the graph that are referenced by anims or lights - // or cameras unique. So we add a prefix to them ... $<rand>_ - // We could also use a counter, but using a random value allows us to - // use just one prefix if we are joining multiple scene hierarchies recursively. - // Chances are quite good we don't collide, so we try that ... - // ---------------------------------------------------------------------------- - - // Allocate space for light sources, cameras and animations - aiLight** ppLights = dest->mLights = (dest->mNumLights - ? new aiLight*[dest->mNumLights] : NULL); - - aiCamera** ppCameras = dest->mCameras = (dest->mNumCameras - ? new aiCamera*[dest->mNumCameras] : NULL); - - aiAnimation** ppAnims = dest->mAnimations = (dest->mNumAnimations - ? new aiAnimation*[dest->mNumAnimations] : NULL); - - for ( int n = static_cast<int>(src.size()-1); n >= 0 ;--n ) /* !!! important !!! */ - { - SceneHelper* cur = &src[n]; - aiNode* node; - - // To offset or not to offset, this is the question - if (n != (int)duplicates[n]) - { - // Get full scene-graph copy - Copy( &node, (*cur)->mRootNode ); - OffsetNodeMeshIndices(node,offset[duplicates[n]]); - - if (flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) { - // (note:) they are already 'offseted' by offset[duplicates[n]] - OffsetNodeMeshIndices(node,offset[n] - offset[duplicates[n]]); - } - } - else // if (n == duplicates[n]) - { - node = (*cur)->mRootNode; - OffsetNodeMeshIndices(node,offset[n]); - } - if (n) // src[0] is the master node - nodes.push_back(NodeAttachmentInfo( node,srcList[n-1].attachToNode,n )); - - // add name prefixes? - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) { - - // or the whole scenegraph - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - AddNodePrefixesChecked(node,(*cur).id,(*cur).idlen,src,n); - } - else AddNodePrefixes(node,(*cur).id,(*cur).idlen); - - // meshes - for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i) { - aiMesh* mesh = (*cur)->mMeshes[i]; - - // rename all bones - for (unsigned int a = 0; a < mesh->mNumBones;++a) { - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - if (!FindNameMatch(mesh->mBones[a]->mName,src,n)) - continue; - } - PrefixString(mesh->mBones[a]->mName,(*cur).id,(*cur).idlen); - } - } - } - - // -------------------------------------------------------------------- - // Copy light sources - for (unsigned int i = 0; i < (*cur)->mNumLights;++i,++ppLights) - { - if (n != (int)duplicates[n]) // duplicate scene? - { - Copy(ppLights, (*cur)->mLights[i]); - } - else *ppLights = (*cur)->mLights[i]; - - - // Add name prefixes? - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) { - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - if (!FindNameMatch((*ppLights)->mName,src,n)) - continue; - } - - PrefixString((*ppLights)->mName,(*cur).id,(*cur).idlen); - } - } - - // -------------------------------------------------------------------- - // Copy cameras - for (unsigned int i = 0; i < (*cur)->mNumCameras;++i,++ppCameras) { - if (n != (int)duplicates[n]) // duplicate scene? - { - Copy(ppCameras, (*cur)->mCameras[i]); - } - else *ppCameras = (*cur)->mCameras[i]; - - // Add name prefixes? - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) { - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - if (!FindNameMatch((*ppCameras)->mName,src,n)) - continue; - } - - PrefixString((*ppCameras)->mName,(*cur).id,(*cur).idlen); - } - } - - // -------------------------------------------------------------------- - // Copy animations - for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i,++ppAnims) { - if (n != (int)duplicates[n]) // duplicate scene? - { - Copy(ppAnims, (*cur)->mAnimations[i]); - } - else *ppAnims = (*cur)->mAnimations[i]; - - // Add name prefixes? - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) { - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - if (!FindNameMatch((*ppAnims)->mName,src,n)) - continue; - } - - PrefixString((*ppAnims)->mName,(*cur).id,(*cur).idlen); - - // don't forget to update all node animation channels - for (unsigned int a = 0; a < (*ppAnims)->mNumChannels;++a) { - if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) { - if (!FindNameMatch((*ppAnims)->mChannels[a]->mNodeName,src,n)) - continue; - } - - PrefixString((*ppAnims)->mChannels[a]->mNodeName,(*cur).id,(*cur).idlen); - } - } - } - } - - // Now build the output graph - AttachToGraph ( master, nodes); - dest->mRootNode = master->mRootNode; - - // Check whether we succeeded at building the output graph - for (std::vector <NodeAttachmentInfo> ::iterator it = nodes.begin(); - it != nodes.end(); ++it) - { - if (!(*it).resolved) { - if (flags & AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS) { - // search for this attachment point in all other imported scenes, too. - for ( unsigned int n = 0; n < src.size();++n ) { - if (n != (*it).src_idx) { - AttachToGraph(src[n].scene,nodes); - if ((*it).resolved) - break; - } - } - } - if (!(*it).resolved) { - ASSIMP_LOG_ERROR_F( "SceneCombiner: Failed to resolve attachment ", (*it).node->mName.data, - " ", (*it).attachToNode->mName.data ); - } - } - } - - // now delete all input scenes. Make sure duplicate scenes aren't - // deleted more than one time - for ( unsigned int n = 0; n < src.size();++n ) { - if (n != duplicates[n]) // duplicate scene? - continue; - - aiScene* deleteMe = src[n].scene; - - // We need to delete the arrays before the destructor is called - - // we are reusing the array members - delete[] deleteMe->mMeshes; deleteMe->mMeshes = NULL; - delete[] deleteMe->mCameras; deleteMe->mCameras = NULL; - delete[] deleteMe->mLights; deleteMe->mLights = NULL; - delete[] deleteMe->mMaterials; deleteMe->mMaterials = NULL; - delete[] deleteMe->mAnimations; deleteMe->mAnimations = NULL; - - deleteMe->mRootNode = NULL; - - // Now we can safely delete the scene - delete deleteMe; - } - - // Check flags - if (!dest->mNumMeshes || !dest->mNumMaterials) { - dest->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - } - - // We're finished -} - -// ------------------------------------------------------------------------------------------------ -// Build a list of unique bones -void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash>& asBones, - std::vector<aiMesh*>::const_iterator it, - std::vector<aiMesh*>::const_iterator end) -{ - unsigned int iOffset = 0; - for (; it != end;++it) { - for (unsigned int l = 0; l < (*it)->mNumBones;++l) { - aiBone* p = (*it)->mBones[l]; - uint32_t itml = SuperFastHash(p->mName.data,(unsigned int)p->mName.length); - - std::list<BoneWithHash>::iterator it2 = asBones.begin(); - std::list<BoneWithHash>::iterator end2 = asBones.end(); - - for (;it2 != end2;++it2) { - if ((*it2).first == itml) { - (*it2).pSrcBones.push_back(BoneSrcIndex(p,iOffset)); - break; - } - } - if (end2 == it2) { - // need to begin a new bone entry - asBones.push_back(BoneWithHash()); - BoneWithHash& btz = asBones.back(); - - // setup members - btz.first = itml; - btz.second = &p->mName; - btz.pSrcBones.push_back(BoneSrcIndex(p,iOffset)); - } - } - iOffset += (*it)->mNumVertices; - } -} - -// ------------------------------------------------------------------------------------------------ -// Merge a list of bones -void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it, - std::vector<aiMesh*>::const_iterator end) -{ - if ( nullptr == out || out->mNumBones == 0 ) { - return; - } - - // find we need to build an unique list of all bones. - // we work with hashes to make the comparisons MUCH faster, - // at least if we have many bones. - std::list<BoneWithHash> asBones; - BuildUniqueBoneList( asBones, it, end ); - - // now create the output bones - out->mNumBones = 0; - out->mBones = new aiBone*[asBones.size()]; - - for (std::list<BoneWithHash>::const_iterator boneIt = asBones.begin(),boneEnd = asBones.end(); boneIt != boneEnd; ++boneIt ) { - // Allocate a bone and setup it's name - aiBone* pc = out->mBones[out->mNumBones++] = new aiBone(); - pc->mName = aiString( *( boneIt->second )); - - std::vector< BoneSrcIndex >::const_iterator wend = boneIt->pSrcBones.end(); - - // Loop through all bones to be joined for this bone - for (std::vector< BoneSrcIndex >::const_iterator wmit = boneIt->pSrcBones.begin(); wmit != wend; ++wmit) { - pc->mNumWeights += (*wmit).first->mNumWeights; - - // NOTE: different offset matrices for bones with equal names - // are - at the moment - not handled correctly. - if (wmit != boneIt->pSrcBones.begin() && pc->mOffsetMatrix != wmit->first->mOffsetMatrix) { - ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment"); - continue; - } - pc->mOffsetMatrix = wmit->first->mOffsetMatrix; - } - - // Allocate the vertex weight array - aiVertexWeight* avw = pc->mWeights = new aiVertexWeight[pc->mNumWeights]; - - // And copy the final weights - adjust the vertex IDs by the - // face index offset of the corresponding mesh. - for (std::vector< BoneSrcIndex >::const_iterator wmit = (*boneIt).pSrcBones.begin(); wmit != (*boneIt).pSrcBones.end(); ++wmit) { - if (wmit == wend) { - break; - } - - aiBone* pip = (*wmit).first; - for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) { - const aiVertexWeight& vfi = pip->mWeights[mp]; - avw->mWeight = vfi.mWeight; - avw->mVertexId = vfi.mVertexId + (*wmit).second; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Merge a list of meshes -void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/, - std::vector<aiMesh*>::const_iterator begin, - std::vector<aiMesh*>::const_iterator end) -{ - if ( nullptr == _out ) { - return; - } - - if (begin == end) { - *_out = NULL; // no meshes ... - return; - } - - // Allocate the output mesh - aiMesh* out = *_out = new aiMesh(); - out->mMaterialIndex = (*begin)->mMaterialIndex; - - std::string name; - // Find out how much output storage we'll need - for (std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it) { - const char *meshName( (*it)->mName.C_Str() ); - name += std::string( meshName ); - if ( it != end - 1 ) { - name += "."; - } - out->mNumVertices += (*it)->mNumVertices; - out->mNumFaces += (*it)->mNumFaces; - out->mNumBones += (*it)->mNumBones; - - // combine primitive type flags - out->mPrimitiveTypes |= (*it)->mPrimitiveTypes; - } - out->mName.Set( name.c_str() ); - - if (out->mNumVertices) { - aiVector3D* pv2; - - // copy vertex positions - if ((**begin).HasPositions()) { - - pv2 = out->mVertices = new aiVector3D[out->mNumVertices]; - for (std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it) { - if ((*it)->mVertices) { - ::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D)); - } - else ASSIMP_LOG_WARN("JoinMeshes: Positions expected but input mesh contains no positions"); - pv2 += (*it)->mNumVertices; - } - } - // copy normals - if ((**begin).HasNormals()) { - - pv2 = out->mNormals = new aiVector3D[out->mNumVertices]; - for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) { - if ((*it)->mNormals) { - ::memcpy(pv2,(*it)->mNormals,(*it)->mNumVertices*sizeof(aiVector3D)); - } else { - ASSIMP_LOG_WARN( "JoinMeshes: Normals expected but input mesh contains no normals" ); - } - pv2 += (*it)->mNumVertices; - } - } - // copy tangents and bi-tangents - if ((**begin).HasTangentsAndBitangents()) { - - pv2 = out->mTangents = new aiVector3D[out->mNumVertices]; - aiVector3D* pv2b = out->mBitangents = new aiVector3D[out->mNumVertices]; - - for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) { - if ((*it)->mTangents) { - ::memcpy(pv2, (*it)->mTangents, (*it)->mNumVertices*sizeof(aiVector3D)); - ::memcpy(pv2b,(*it)->mBitangents,(*it)->mNumVertices*sizeof(aiVector3D)); - } else { - ASSIMP_LOG_WARN( "JoinMeshes: Tangents expected but input mesh contains no tangents" ); - } - pv2 += (*it)->mNumVertices; - pv2b += (*it)->mNumVertices; - } - } - // copy texture coordinates - unsigned int n = 0; - while ((**begin).HasTextureCoords(n)) { - out->mNumUVComponents[n] = (*begin)->mNumUVComponents[n]; - - pv2 = out->mTextureCoords[n] = new aiVector3D[out->mNumVertices]; - for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) { - if ((*it)->mTextureCoords[n]) { - ::memcpy(pv2,(*it)->mTextureCoords[n],(*it)->mNumVertices*sizeof(aiVector3D)); - } else { - ASSIMP_LOG_WARN( "JoinMeshes: UVs expected but input mesh contains no UVs" ); - } - pv2 += (*it)->mNumVertices; - } - ++n; - } - // copy vertex colors - n = 0; - while ((**begin).HasVertexColors(n)) { - aiColor4D *pVec2 = out->mColors[n] = new aiColor4D[out->mNumVertices]; - for ( std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it ) { - if ((*it)->mColors[n]) { - ::memcpy( pVec2, (*it)->mColors[ n ], (*it)->mNumVertices * sizeof( aiColor4D ) ) ; - } else { - ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" ); - } - pVec2 += (*it)->mNumVertices; - } - ++n; - } - } - - if (out->mNumFaces) // just for safety - { - // copy faces - out->mFaces = new aiFace[out->mNumFaces]; - aiFace* pf2 = out->mFaces; - - unsigned int ofs = 0; - for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) { - for (unsigned int m = 0; m < (*it)->mNumFaces;++m,++pf2) { - aiFace& face = (*it)->mFaces[m]; - pf2->mNumIndices = face.mNumIndices; - pf2->mIndices = face.mIndices; - - if (ofs) { - // add the offset to the vertex - for (unsigned int q = 0; q < face.mNumIndices; ++q) - face.mIndices[q] += ofs; - } - face.mIndices = NULL; - } - ofs += (*it)->mNumVertices; - } - } - - // bones - as this is quite lengthy, I moved the code to a separate function - if (out->mNumBones) - MergeBones(out,begin,end); - - // delete all source meshes - for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) - delete *it; -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::MergeMaterials(aiMaterial** dest, - std::vector<aiMaterial*>::const_iterator begin, - std::vector<aiMaterial*>::const_iterator end) -{ - if ( nullptr == dest ) { - return; - } - - if (begin == end) { - *dest = NULL; // no materials ... - return; - } - - // Allocate the output material - aiMaterial* out = *dest = new aiMaterial(); - - // Get the maximal number of properties - unsigned int size = 0; - for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) { - size += (*it)->mNumProperties; - } - - out->Clear(); - delete[] out->mProperties; - - out->mNumAllocated = size; - out->mNumProperties = 0; - out->mProperties = new aiMaterialProperty*[out->mNumAllocated]; - - for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) { - for(unsigned int i = 0; i < (*it)->mNumProperties; ++i) { - aiMaterialProperty* sprop = (*it)->mProperties[i]; - - // Test if we already have a matching property - const aiMaterialProperty* prop_exist; - if(aiGetMaterialProperty(out, sprop->mKey.C_Str(), sprop->mSemantic, sprop->mIndex, &prop_exist) != AI_SUCCESS) { - // If not, we add it to the new material - aiMaterialProperty* prop = out->mProperties[out->mNumProperties] = new aiMaterialProperty(); - - prop->mDataLength = sprop->mDataLength; - prop->mData = new char[prop->mDataLength]; - ::memcpy(prop->mData, sprop->mData, prop->mDataLength); - - prop->mIndex = sprop->mIndex; - prop->mSemantic = sprop->mSemantic; - prop->mKey = sprop->mKey; - prop->mType = sprop->mType; - - out->mNumProperties++; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -template <typename Type> -inline -void CopyPtrArray (Type**& dest, const Type* const * src, ai_uint num) { - if (!num) { - dest = NULL; - return; - } - dest = new Type*[num]; - for (ai_uint i = 0; i < num;++i) { - SceneCombiner::Copy(&dest[i],src[i]); - } -} - -// ------------------------------------------------------------------------------------------------ -template <typename Type> -inline -void GetArrayCopy(Type*& dest, ai_uint num ) { - if ( !dest ) { - return; - } - Type* old = dest; - - dest = new Type[num]; - ::memcpy(dest, old, sizeof(Type) * num); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - // reuse the old scene or allocate a new? - if (*_dest) { - (*_dest)->~aiScene(); - new (*_dest) aiScene(); - } else { - *_dest = new aiScene(); - } - - ::memcpy(*_dest,src,sizeof(aiScene)); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - if (allocate) { - *_dest = new aiScene(); - } - aiScene* dest = *_dest; - ai_assert(nullptr != dest); - - // copy metadata - if ( nullptr != src->mMetaData ) { - dest->mMetaData = new aiMetadata( *src->mMetaData ); - } - - // copy animations - dest->mNumAnimations = src->mNumAnimations; - CopyPtrArray(dest->mAnimations,src->mAnimations, - dest->mNumAnimations); - - // copy textures - dest->mNumTextures = src->mNumTextures; - CopyPtrArray(dest->mTextures,src->mTextures, - dest->mNumTextures); - - // copy materials - dest->mNumMaterials = src->mNumMaterials; - CopyPtrArray(dest->mMaterials,src->mMaterials, - dest->mNumMaterials); - - // copy lights - dest->mNumLights = src->mNumLights; - CopyPtrArray(dest->mLights,src->mLights, - dest->mNumLights); - - // copy cameras - dest->mNumCameras = src->mNumCameras; - CopyPtrArray(dest->mCameras,src->mCameras, - dest->mNumCameras); - - // copy meshes - dest->mNumMeshes = src->mNumMeshes; - CopyPtrArray(dest->mMeshes,src->mMeshes, - dest->mNumMeshes); - - // now - copy the root node of the scene (deep copy, too) - Copy( &dest->mRootNode, src->mRootNode); - - // and keep the flags ... - dest->mFlags = src->mFlags; - - // source private data might be NULL if the scene is user-allocated (i.e. for use with the export API) - if (dest->mPrivate != NULL) { - ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0; - } -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiMesh* dest = *_dest = new aiMesh(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiMesh)); - - // and reallocate all arrays - GetArrayCopy( dest->mVertices, dest->mNumVertices ); - GetArrayCopy( dest->mNormals , dest->mNumVertices ); - GetArrayCopy( dest->mTangents, dest->mNumVertices ); - GetArrayCopy( dest->mBitangents, dest->mNumVertices ); - - unsigned int n = 0; - while (dest->HasTextureCoords(n)) - GetArrayCopy( dest->mTextureCoords[n++], dest->mNumVertices ); - - n = 0; - while (dest->HasVertexColors(n)) - GetArrayCopy( dest->mColors[n++], dest->mNumVertices ); - - // make a deep copy of all bones - CopyPtrArray(dest->mBones,dest->mBones,dest->mNumBones); - - // make a deep copy of all faces - GetArrayCopy(dest->mFaces,dest->mNumFaces); - for (unsigned int i = 0; i < dest->mNumFaces;++i) { - aiFace& f = dest->mFaces[i]; - GetArrayCopy(f.mIndices,f.mNumIndices); - } - - // make a deep copy of all blend shapes - CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) { - if (nullptr == _dest || nullptr == src) { - return; - } - - aiAnimMesh* dest = *_dest = new aiAnimMesh(); - - // get a flat copy - ::memcpy(dest, src, sizeof(aiAnimMesh)); - - // and reallocate all arrays - GetArrayCopy(dest->mVertices, dest->mNumVertices); - GetArrayCopy(dest->mNormals, dest->mNumVertices); - GetArrayCopy(dest->mTangents, dest->mNumVertices); - GetArrayCopy(dest->mBitangents, dest->mNumVertices); - - unsigned int n = 0; - while (dest->HasTextureCoords(n)) - GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices); - - n = 0; - while (dest->HasVertexColors(n)) - GetArrayCopy(dest->mColors[n++], dest->mNumVertices); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiMaterial* dest = (aiMaterial*) ( *_dest = new aiMaterial() ); - - dest->Clear(); - delete[] dest->mProperties; - - dest->mNumAllocated = src->mNumAllocated; - dest->mNumProperties = src->mNumProperties; - dest->mProperties = new aiMaterialProperty* [dest->mNumAllocated]; - - for (unsigned int i = 0; i < dest->mNumProperties;++i) - { - aiMaterialProperty* prop = dest->mProperties[i] = new aiMaterialProperty(); - aiMaterialProperty* sprop = src->mProperties[i]; - - prop->mDataLength = sprop->mDataLength; - prop->mData = new char[prop->mDataLength]; - ::memcpy(prop->mData,sprop->mData,prop->mDataLength); - - prop->mIndex = sprop->mIndex; - prop->mSemantic = sprop->mSemantic; - prop->mKey = sprop->mKey; - prop->mType = sprop->mType; - } -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy(aiTexture** _dest, const aiTexture* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiTexture* dest = *_dest = new aiTexture(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiTexture)); - - // and reallocate all arrays. We must do it manually here - const char* old = (const char*)dest->pcData; - if (old) - { - unsigned int cpy; - if (!dest->mHeight)cpy = dest->mWidth; - else cpy = dest->mHeight * dest->mWidth * sizeof(aiTexel); - - if (!cpy) - { - dest->pcData = NULL; - return; - } - // the cast is legal, the aiTexel c'tor does nothing important - dest->pcData = (aiTexel*) new char[cpy]; - ::memcpy(dest->pcData, old, cpy); - } -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiAnimation* dest = *_dest = new aiAnimation(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiAnimation)); - - // and reallocate all arrays - CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels ); - CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels ); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiNodeAnim* dest = *_dest = new aiNodeAnim(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiNodeAnim)); - - // and reallocate all arrays - GetArrayCopy( dest->mPositionKeys, dest->mNumPositionKeys ); - GetArrayCopy( dest->mScalingKeys, dest->mNumScalingKeys ); - GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys ); -} - -void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiMeshMorphAnim)); - - // and reallocate all arrays - GetArrayCopy( dest->mKeys, dest->mNumKeys ); - for (ai_uint i = 0; i < dest->mNumKeys;++i) { - dest->mKeys[i].mValues = new unsigned int[dest->mKeys[i].mNumValuesAndWeights]; - dest->mKeys[i].mWeights = new double[dest->mKeys[i].mNumValuesAndWeights]; - ::memcpy(dest->mKeys[i].mValues, src->mKeys[i].mValues, dest->mKeys[i].mNumValuesAndWeights * sizeof(unsigned int)); - ::memcpy(dest->mKeys[i].mWeights, src->mKeys[i].mWeights, dest->mKeys[i].mNumValuesAndWeights * sizeof(double)); - } -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiCamera* dest = *_dest = new aiCamera(); - - // get a flat copy, that's already OK - ::memcpy(dest,src,sizeof(aiCamera)); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy(aiLight** _dest, const aiLight* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiLight* dest = *_dest = new aiLight(); - - // get a flat copy, that's already OK - ::memcpy(dest,src,sizeof(aiLight)); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy(aiBone** _dest, const aiBone* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - aiBone* dest = *_dest = new aiBone(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiBone)); - - // and reallocate all arrays - GetArrayCopy( dest->mWeights, dest->mNumWeights ); -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy (aiNode** _dest, const aiNode* src) -{ - ai_assert(NULL != _dest && NULL != src); - - aiNode* dest = *_dest = new aiNode(); - - // get a flat copy - ::memcpy(dest,src,sizeof(aiNode)); - - if (src->mMetaData) { - Copy(&dest->mMetaData, src->mMetaData); - } - - // and reallocate all arrays - GetArrayCopy( dest->mMeshes, dest->mNumMeshes ); - CopyPtrArray( dest->mChildren, src->mChildren,dest->mNumChildren); - - // need to set the mParent fields to the created aiNode. - for( unsigned int i = 0; i < dest->mNumChildren; i ++ ) { - dest->mChildren[i]->mParent = dest; - } -} - -// ------------------------------------------------------------------------------------------------ -void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src) { - if ( nullptr == _dest || nullptr == src ) { - return; - } - - if ( 0 == src->mNumProperties ) { - return; - } - - aiMetadata* dest = *_dest = aiMetadata::Alloc( src->mNumProperties ); - std::copy(src->mKeys, src->mKeys + src->mNumProperties, dest->mKeys); - - dest->mValues = new aiMetadataEntry[src->mNumProperties]; - for (unsigned int i = 0; i < src->mNumProperties; ++i) { - aiMetadataEntry& in = src->mValues[i]; - aiMetadataEntry& out = dest->mValues[i]; - out.mType = in.mType; - switch (dest->mValues[i].mType) { - case AI_BOOL: - out.mData = new bool(*static_cast<bool*>(in.mData)); - break; - case AI_INT32: - out.mData = new int32_t(*static_cast<int32_t*>(in.mData)); - break; - case AI_UINT64: - out.mData = new uint64_t(*static_cast<uint64_t*>(in.mData)); - break; - case AI_FLOAT: - out.mData = new float(*static_cast<float*>(in.mData)); - break; - case AI_DOUBLE: - out.mData = new double(*static_cast<double*>(in.mData)); - break; - case AI_AISTRING: - out.mData = new aiString(*static_cast<aiString*>(in.mData)); - break; - case AI_AIVECTOR3D: - out.mData = new aiVector3D(*static_cast<aiVector3D*>(in.mData)); - break; - default: - ai_assert(false); - break; - } - } -} - -} // Namespace Assimp - diff --git a/thirdparty/assimp/code/Common/ScenePreprocessor.cpp b/thirdparty/assimp/code/Common/ScenePreprocessor.cpp deleted file mode 100644 index 432a3d7666..0000000000 --- a/thirdparty/assimp/code/Common/ScenePreprocessor.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#include "ScenePreprocessor.h" -#include <assimp/ai_assert.h> -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> - - -using namespace Assimp; - -// --------------------------------------------------------------------------------------------- -void ScenePreprocessor::ProcessScene () -{ - ai_assert(scene != NULL); - - // Process all meshes - for (unsigned int i = 0; i < scene->mNumMeshes;++i) - ProcessMesh(scene->mMeshes[i]); - - // - nothing to do for nodes for the moment - // - nothing to do for textures for the moment - // - nothing to do for lights for the moment - // - nothing to do for cameras for the moment - - // Process all animations - for (unsigned int i = 0; i < scene->mNumAnimations;++i) - ProcessAnimation(scene->mAnimations[i]); - - // Generate a default material if none was specified - if (!scene->mNumMaterials && scene->mNumMeshes) { - scene->mMaterials = new aiMaterial*[2]; - aiMaterial* helper; - - aiString name; - - scene->mMaterials[scene->mNumMaterials] = helper = new aiMaterial(); - aiColor3D clr(0.6f,0.6f,0.6f); - helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE); - - // setup the default name to make this material identifiable - name.Set(AI_DEFAULT_MATERIAL_NAME); - helper->AddProperty(&name,AI_MATKEY_NAME); - - ASSIMP_LOG_DEBUG("ScenePreprocessor: Adding default material \'" AI_DEFAULT_MATERIAL_NAME "\'"); - - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - scene->mMeshes[i]->mMaterialIndex = scene->mNumMaterials; - } - - scene->mNumMaterials++; - } -} - -// --------------------------------------------------------------------------------------------- -void ScenePreprocessor::ProcessMesh (aiMesh* mesh) -{ - // If aiMesh::mNumUVComponents is *not* set assign the default value of 2 - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (!mesh->mTextureCoords[i]) { - mesh->mNumUVComponents[i] = 0; - } else { - if (!mesh->mNumUVComponents[i]) - mesh->mNumUVComponents[i] = 2; - - aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices; - - // Ensure unused components are zeroed. This will make 1D texture channels work - // as if they were 2D channels .. just in case an application doesn't handle - // this case - if (2 == mesh->mNumUVComponents[i]) { - for (; p != end; ++p) - p->z = 0.f; - } - else if (1 == mesh->mNumUVComponents[i]) { - for (; p != end; ++p) - p->z = p->y = 0.f; - } - else if (3 == mesh->mNumUVComponents[i]) { - // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element - for (; p != end; ++p) { - if (p->z != 0) - break; - } - if (p == end) { - ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D."); - mesh->mNumUVComponents[i] = 2; - } - } - } - } - - // If the information which primitive types are there in the - // mesh is currently not available, compute it. - if (!mesh->mPrimitiveTypes) { - for (unsigned int a = 0; a < mesh->mNumFaces; ++a) { - aiFace& face = mesh->mFaces[a]; - switch (face.mNumIndices) - { - case 3u: - mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - - case 2u: - mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - - case 1u: - mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - - default: - mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - break; - } - } - } - - // If tangents and normals are given but no bitangents compute them - if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) { - - mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; - for (unsigned int i = 0; i < mesh->mNumVertices;++i) { - mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i]; - } - } -} - -// --------------------------------------------------------------------------------------------- -void ScenePreprocessor::ProcessAnimation (aiAnimation* anim) -{ - double first = 10e10, last = -10e10; - for (unsigned int i = 0; i < anim->mNumChannels;++i) { - aiNodeAnim* channel = anim->mChannels[i]; - - /* If the exact duration of the animation is not given - * compute it now. - */ - if (anim->mDuration == -1.) { - - // Position keys - for (unsigned int j = 0; j < channel->mNumPositionKeys;++j) { - aiVectorKey& key = channel->mPositionKeys[j]; - first = std::min (first, key.mTime); - last = std::max (last, key.mTime); - } - - // Scaling keys - for (unsigned int j = 0; j < channel->mNumScalingKeys;++j ) { - aiVectorKey& key = channel->mScalingKeys[j]; - first = std::min (first, key.mTime); - last = std::max (last, key.mTime); - } - - // Rotation keys - for (unsigned int j = 0; j < channel->mNumRotationKeys;++j ) { - aiQuatKey& key = channel->mRotationKeys[ j ]; - first = std::min (first, key.mTime); - last = std::max (last, key.mTime); - } - } - - /* Check whether the animation channel has no rotation - * or position tracks. In this case we generate a dummy - * track from the information we have in the transformation - * matrix of the corresponding node. - */ - if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys) { - // Find the node that belongs to this animation - aiNode* node = scene->mRootNode->FindNode(channel->mNodeName); - if (node) // ValidateDS will complain later if 'node' is NULL - { - // Decompose the transformation matrix of the node - aiVector3D scaling, position; - aiQuaternion rotation; - - node->mTransformation.Decompose(scaling, rotation,position); - - // No rotation keys? Generate a dummy track - if (!channel->mNumRotationKeys) { - channel->mNumRotationKeys = 1; - channel->mRotationKeys = new aiQuatKey[1]; - aiQuatKey& q = channel->mRotationKeys[0]; - - q.mTime = 0.; - q.mValue = rotation; - - ASSIMP_LOG_DEBUG("ScenePreprocessor: Dummy rotation track has been generated"); - } - - // No scaling keys? Generate a dummy track - if (!channel->mNumScalingKeys) { - channel->mNumScalingKeys = 1; - channel->mScalingKeys = new aiVectorKey[1]; - aiVectorKey& q = channel->mScalingKeys[0]; - - q.mTime = 0.; - q.mValue = scaling; - - ASSIMP_LOG_DEBUG("ScenePreprocessor: Dummy scaling track has been generated"); - } - - // No position keys? Generate a dummy track - if (!channel->mNumPositionKeys) { - channel->mNumPositionKeys = 1; - channel->mPositionKeys = new aiVectorKey[1]; - aiVectorKey& q = channel->mPositionKeys[0]; - - q.mTime = 0.; - q.mValue = position; - - ASSIMP_LOG_DEBUG("ScenePreprocessor: Dummy position track has been generated"); - } - } - } - } - - if (anim->mDuration == -1.) { - ASSIMP_LOG_DEBUG("ScenePreprocessor: Setting animation duration"); - anim->mDuration = last - std::min( first, 0. ); - } -} diff --git a/thirdparty/assimp/code/Common/ScenePreprocessor.h b/thirdparty/assimp/code/Common/ScenePreprocessor.h deleted file mode 100644 index 3f4c8d7c3f..0000000000 --- a/thirdparty/assimp/code/Common/ScenePreprocessor.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to search all meshes for - degenerated faces */ -#ifndef AI_SCENE_PREPROCESSOR_H_INC -#define AI_SCENE_PREPROCESSOR_H_INC - -#include <assimp/defs.h> -#include <stddef.h> - -struct aiScene; -struct aiAnimation; -struct aiMesh; - -class ScenePreprocessorTest; -namespace Assimp { - -// ---------------------------------------------------------------------------------- -/** ScenePreprocessor: Preprocess a scene before any post-processing - * steps are executed. - * - * The step computes data that needn't necessarily be provided by the - * importer, such as aiMesh::mPrimitiveTypes. -*/ -// ---------------------------------------------------------------------------------- -class ASSIMP_API ScenePreprocessor -{ - // Make ourselves a friend of the corresponding test unit. - friend class ::ScenePreprocessorTest; -public: - - // ---------------------------------------------------------------- - /** Default c'tpr. Use SetScene() to assign a scene to the object. - */ - ScenePreprocessor() - : scene (NULL) - {} - - /** Constructs the object and assigns a specific scene to it - */ - ScenePreprocessor(aiScene* _scene) - : scene (_scene) - {} - - // ---------------------------------------------------------------- - /** Assign a (new) scene to the object. - * - * One 'SceneProcessor' can be used for multiple scenes. - * Call ProcessScene to have the scene preprocessed. - * @param sc Scene to be processed. - */ - void SetScene (aiScene* sc) { - scene = sc; - } - - // ---------------------------------------------------------------- - /** Preprocess the current scene - */ - void ProcessScene (); - -protected: - - // ---------------------------------------------------------------- - /** Preprocess an animation in the scene - * @param anim Anim to be preprocessed. - */ - void ProcessAnimation (aiAnimation* anim); - - - // ---------------------------------------------------------------- - /** Preprocess a mesh in the scene - * @param mesh Mesh to be preprocessed. - */ - void ProcessMesh (aiMesh* mesh); - -protected: - - //! Scene we're currently working on - aiScene* scene; -}; - - -} // ! end namespace Assimp - -#endif // include guard diff --git a/thirdparty/assimp/code/Common/ScenePrivate.h b/thirdparty/assimp/code/Common/ScenePrivate.h deleted file mode 100644 index f336aafc9a..0000000000 --- a/thirdparty/assimp/code/Common/ScenePrivate.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Stuff to deal with aiScene::mPrivate - */ -#pragma once -#ifndef AI_SCENEPRIVATE_H_INCLUDED -#define AI_SCENEPRIVATE_H_INCLUDED - -#include <assimp/ai_assert.h> -#include <assimp/scene.h> - -namespace Assimp { - -// Forward declarations -class Importer; - -struct ScenePrivateData { - // The struct constructor. - ScenePrivateData() AI_NO_EXCEPT; - - // Importer that originally loaded the scene though the C-API - // If set, this object is owned by this private data instance. - Assimp::Importer* mOrigImporter; - - // List of post-processing steps already applied to the scene. - unsigned int mPPStepsApplied; - - // true if the scene is a copy made with aiCopyScene() - // or the corresponding C++ API. This means that user code - // may have made modifications to it, so mPPStepsApplied - // and mOrigImporter are no longer safe to rely on and only - // serve informative purposes. - bool mIsCopy; -}; - -inline -ScenePrivateData::ScenePrivateData() AI_NO_EXCEPT -: mOrigImporter( nullptr ) -, mPPStepsApplied( 0 ) -, mIsCopy( false ) { - // empty -} - -// Access private data stored in the scene -inline -ScenePrivateData* ScenePriv(aiScene* in) { - ai_assert( nullptr != in ); - if ( nullptr == in ) { - return nullptr; - } - return static_cast<ScenePrivateData*>(in->mPrivate); -} - -inline -const ScenePrivateData* ScenePriv(const aiScene* in) { - ai_assert( nullptr != in ); - if ( nullptr == in ) { - return nullptr; - } - return static_cast<const ScenePrivateData*>(in->mPrivate); -} - -} // Namespace Assimp - -#endif // AI_SCENEPRIVATE_H_INCLUDED diff --git a/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp b/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp deleted file mode 100644 index 06cfe034e9..0000000000 --- a/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file SkeletonMeshBuilder.cpp - * @brief Implementation of a little class to construct a dummy mesh for a skeleton - */ - -#include <assimp/scene.h> -#include <assimp/SkeletonMeshBuilder.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// The constructor processes the given scene and adds a mesh there. -SkeletonMeshBuilder::SkeletonMeshBuilder( aiScene* pScene, aiNode* root, bool bKnobsOnly) -{ - // nothing to do if there's mesh data already present at the scene - if( pScene->mNumMeshes > 0 || pScene->mRootNode == NULL) - return; - - if (!root) - root = pScene->mRootNode; - - mKnobsOnly = bKnobsOnly; - - // build some faces around each node - CreateGeometry( root ); - - // create a mesh to hold all the generated faces - pScene->mNumMeshes = 1; - pScene->mMeshes = new aiMesh*[1]; - pScene->mMeshes[0] = CreateMesh(); - // and install it at the root node - root->mNumMeshes = 1; - root->mMeshes = new unsigned int[1]; - root->mMeshes[0] = 0; - - // create a dummy material for the mesh - if(pScene->mNumMaterials==0){ - pScene->mNumMaterials = 1; - pScene->mMaterials = new aiMaterial*[1]; - pScene->mMaterials[0] = CreateMaterial(); - } -} - -// ------------------------------------------------------------------------------------------------ -// Recursively builds a simple mesh representation for the given node -void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode) -{ - // add a joint entry for the node. - const unsigned int vertexStartIndex = static_cast<unsigned int>(mVertices.size()); - - // now build the geometry. - if( pNode->mNumChildren > 0 && !mKnobsOnly) - { - // If the node has children, we build little pointers to each of them - for( unsigned int a = 0; a < pNode->mNumChildren; a++) - { - // find a suitable coordinate system - const aiMatrix4x4& childTransform = pNode->mChildren[a]->mTransformation; - aiVector3D childpos( childTransform.a4, childTransform.b4, childTransform.c4); - ai_real distanceToChild = childpos.Length(); - if( distanceToChild < 0.0001) - continue; - aiVector3D up = aiVector3D( childpos).Normalize(); - - aiVector3D orth( 1.0, 0.0, 0.0); - if( std::fabs( orth * up) > 0.99) - orth.Set( 0.0, 1.0, 0.0); - - aiVector3D front = (up ^ orth).Normalize(); - aiVector3D side = (front ^ up).Normalize(); - - unsigned int localVertexStart = static_cast<unsigned int>(mVertices.size()); - mVertices.push_back( -front * distanceToChild * (ai_real)0.1); - mVertices.push_back( childpos); - mVertices.push_back( -side * distanceToChild * (ai_real)0.1); - mVertices.push_back( -side * distanceToChild * (ai_real)0.1); - mVertices.push_back( childpos); - mVertices.push_back( front * distanceToChild * (ai_real)0.1); - mVertices.push_back( front * distanceToChild * (ai_real)0.1); - mVertices.push_back( childpos); - mVertices.push_back( side * distanceToChild * (ai_real)0.1); - mVertices.push_back( side * distanceToChild * (ai_real)0.1); - mVertices.push_back( childpos); - mVertices.push_back( -front * distanceToChild * (ai_real)0.1); - - mFaces.push_back( Face( localVertexStart + 0, localVertexStart + 1, localVertexStart + 2)); - mFaces.push_back( Face( localVertexStart + 3, localVertexStart + 4, localVertexStart + 5)); - mFaces.push_back( Face( localVertexStart + 6, localVertexStart + 7, localVertexStart + 8)); - mFaces.push_back( Face( localVertexStart + 9, localVertexStart + 10, localVertexStart + 11)); - } - } - else - { - // if the node has no children, it's an end node. Put a little knob there instead - aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4); - ai_real sizeEstimate = ownpos.Length() * ai_real( 0.18 ); - - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate)); - - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0)); - mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate)); - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0)); - - mFaces.push_back( Face( vertexStartIndex + 0, vertexStartIndex + 1, vertexStartIndex + 2)); - mFaces.push_back( Face( vertexStartIndex + 3, vertexStartIndex + 4, vertexStartIndex + 5)); - mFaces.push_back( Face( vertexStartIndex + 6, vertexStartIndex + 7, vertexStartIndex + 8)); - mFaces.push_back( Face( vertexStartIndex + 9, vertexStartIndex + 10, vertexStartIndex + 11)); - mFaces.push_back( Face( vertexStartIndex + 12, vertexStartIndex + 13, vertexStartIndex + 14)); - mFaces.push_back( Face( vertexStartIndex + 15, vertexStartIndex + 16, vertexStartIndex + 17)); - mFaces.push_back( Face( vertexStartIndex + 18, vertexStartIndex + 19, vertexStartIndex + 20)); - mFaces.push_back( Face( vertexStartIndex + 21, vertexStartIndex + 22, vertexStartIndex + 23)); - } - - unsigned int numVertices = static_cast<unsigned int>(mVertices.size() - vertexStartIndex); - if( numVertices > 0) - { - // create a bone affecting all the newly created vertices - aiBone* bone = new aiBone; - mBones.push_back( bone); - bone->mName = pNode->mName; - - // calculate the bone offset matrix by concatenating the inverse transformations of all parents - bone->mOffsetMatrix = aiMatrix4x4( pNode->mTransformation).Inverse(); - for( aiNode* parent = pNode->mParent; parent != NULL; parent = parent->mParent) - bone->mOffsetMatrix = aiMatrix4x4( parent->mTransformation).Inverse() * bone->mOffsetMatrix; - - // add all the vertices to the bone's influences - bone->mNumWeights = numVertices; - bone->mWeights = new aiVertexWeight[numVertices]; - for( unsigned int a = 0; a < numVertices; a++) - bone->mWeights[a] = aiVertexWeight( vertexStartIndex + a, 1.0); - - // HACK: (thom) transform all vertices to the bone's local space. Should be done before adding - // them to the array, but I'm tired now and I'm annoyed. - aiMatrix4x4 boneToMeshTransform = aiMatrix4x4( bone->mOffsetMatrix).Inverse(); - for( unsigned int a = vertexStartIndex; a < mVertices.size(); a++) - mVertices[a] = boneToMeshTransform * mVertices[a]; - } - - // and finally recurse into the children list - for( unsigned int a = 0; a < pNode->mNumChildren; a++) - CreateGeometry( pNode->mChildren[a]); -} - -// ------------------------------------------------------------------------------------------------ -// Creates the mesh from the internally accumulated stuff and returns it. -aiMesh* SkeletonMeshBuilder::CreateMesh() -{ - aiMesh* mesh = new aiMesh(); - - // add points - mesh->mNumVertices = static_cast<unsigned int>(mVertices.size()); - mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - std::copy( mVertices.begin(), mVertices.end(), mesh->mVertices); - - mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - - // add faces - mesh->mNumFaces = static_cast<unsigned int>(mFaces.size()); - mesh->mFaces = new aiFace[mesh->mNumFaces]; - for( unsigned int a = 0; a < mesh->mNumFaces; a++) - { - const Face& inface = mFaces[a]; - aiFace& outface = mesh->mFaces[a]; - outface.mNumIndices = 3; - outface.mIndices = new unsigned int[3]; - outface.mIndices[0] = inface.mIndices[0]; - outface.mIndices[1] = inface.mIndices[1]; - outface.mIndices[2] = inface.mIndices[2]; - - // Compute per-face normals ... we don't want the bones to be smoothed ... they're built to visualize - // the skeleton, so it's good if there's a visual difference to the rest of the geometry - aiVector3D nor = ((mVertices[inface.mIndices[2]] - mVertices[inface.mIndices[0]]) ^ - (mVertices[inface.mIndices[1]] - mVertices[inface.mIndices[0]])); - - if (nor.Length() < 1e-5) /* ensure that FindInvalidData won't remove us ...*/ - nor = aiVector3D(1.0,0.0,0.0); - - for (unsigned int n = 0; n < 3; ++n) - mesh->mNormals[inface.mIndices[n]] = nor; - } - - // add the bones - mesh->mNumBones = static_cast<unsigned int>(mBones.size()); - mesh->mBones = new aiBone*[mesh->mNumBones]; - std::copy( mBones.begin(), mBones.end(), mesh->mBones); - - // default - mesh->mMaterialIndex = 0; - - return mesh; -} - -// ------------------------------------------------------------------------------------------------ -// Creates a dummy material and returns it. -aiMaterial* SkeletonMeshBuilder::CreateMaterial() -{ - aiMaterial* matHelper = new aiMaterial; - - // Name - aiString matName( std::string( "SkeletonMaterial")); - matHelper->AddProperty( &matName, AI_MATKEY_NAME); - - // Prevent backface culling - const int no_cull = 1; - matHelper->AddProperty(&no_cull,1,AI_MATKEY_TWOSIDED); - - return matHelper; -} diff --git a/thirdparty/assimp/code/Common/SpatialSort.cpp b/thirdparty/assimp/code/Common/SpatialSort.cpp deleted file mode 100644 index a4f3a4e4b8..0000000000 --- a/thirdparty/assimp/code/Common/SpatialSort.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the helper class to quickly find vertices close to a given position */ - -#include <assimp/SpatialSort.h> -#include <assimp/ai_assert.h> - -using namespace Assimp; - -// CHAR_BIT seems to be defined under MVSC, but not under GCC. Pray that the correct value is 8. -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif - -// ------------------------------------------------------------------------------------------------ -// Constructs a spatially sorted representation from the given position array. -SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, - unsigned int pElementOffset) - - // define the reference plane. We choose some arbitrary vector away from all basic axises - // in the hope that no model spreads all its vertices along this plane. - : mPlaneNormal(0.8523f, 0.34321f, 0.5736f) -{ - mPlaneNormal.Normalize(); - Fill(pPositions,pNumPositions,pElementOffset); -} - -// ------------------------------------------------------------------------------------------------ -SpatialSort :: SpatialSort() -: mPlaneNormal(0.8523f, 0.34321f, 0.5736f) -{ - mPlaneNormal.Normalize(); -} - -// ------------------------------------------------------------------------------------------------ -// Destructor -SpatialSort::~SpatialSort() -{ - // nothing to do here, everything destructs automatically -} - -// ------------------------------------------------------------------------------------------------ -void SpatialSort::Fill( const aiVector3D* pPositions, unsigned int pNumPositions, - unsigned int pElementOffset, - bool pFinalize /*= true */) -{ - mPositions.clear(); - Append(pPositions,pNumPositions,pElementOffset,pFinalize); -} - -// ------------------------------------------------------------------------------------------------ -void SpatialSort :: Finalize() -{ - std::sort( mPositions.begin(), mPositions.end()); -} - -// ------------------------------------------------------------------------------------------------ -void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositions, - unsigned int pElementOffset, - bool pFinalize /*= true */) -{ - // store references to all given positions along with their distance to the reference plane - const size_t initial = mPositions.size(); - mPositions.reserve(initial + (pFinalize?pNumPositions:pNumPositions*2)); - for( unsigned int a = 0; a < pNumPositions; a++) - { - const char* tempPointer = reinterpret_cast<const char*> (pPositions); - const aiVector3D* vec = reinterpret_cast<const aiVector3D*> (tempPointer + a * pElementOffset); - - // store position by index and distance - ai_real distance = *vec * mPlaneNormal; - mPositions.push_back( Entry( static_cast<unsigned int>(a+initial), *vec, distance)); - } - - if (pFinalize) { - // now sort the array ascending by distance. - Finalize(); - } -} - -// ------------------------------------------------------------------------------------------------ -// Returns an iterator for all positions close to the given position. -void SpatialSort::FindPositions( const aiVector3D& pPosition, - ai_real pRadius, std::vector<unsigned int>& poResults) const -{ - const ai_real dist = pPosition * mPlaneNormal; - const ai_real minDist = dist - pRadius, maxDist = dist + pRadius; - - // clear the array - poResults.clear(); - - // quick check for positions outside the range - if( mPositions.size() == 0) - return; - if( maxDist < mPositions.front().mDistance) - return; - if( minDist > mPositions.back().mDistance) - return; - - // do a binary search for the minimal distance to start the iteration there - unsigned int index = (unsigned int)mPositions.size() / 2; - unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4; - while( binaryStepSize > 1) - { - if( mPositions[index].mDistance < minDist) - index += binaryStepSize; - else - index -= binaryStepSize; - - binaryStepSize /= 2; - } - - // depending on the direction of the last step we need to single step a bit back or forth - // to find the actual beginning element of the range - while( index > 0 && mPositions[index].mDistance > minDist) - index--; - while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist) - index++; - - // Mow start iterating from there until the first position lays outside of the distance range. - // Add all positions inside the distance range within the given radius to the result aray - std::vector<Entry>::const_iterator it = mPositions.begin() + index; - const ai_real pSquared = pRadius*pRadius; - while( it->mDistance < maxDist) - { - if( (it->mPosition - pPosition).SquareLength() < pSquared) - poResults.push_back( it->mIndex); - ++it; - if( it == mPositions.end()) - break; - } - - // that's it -} - -namespace { - - // Binary, signed-integer representation of a single-precision floating-point value. - // IEEE 754 says: "If two floating-point numbers in the same format are ordered then they are - // ordered the same way when their bits are reinterpreted as sign-magnitude integers." - // This allows us to convert all floating-point numbers to signed integers of arbitrary size - // and then use them to work with ULPs (Units in the Last Place, for high-precision - // computations) or to compare them (integer comparisons are faster than floating-point - // comparisons on many platforms). - typedef ai_int BinFloat; - - // -------------------------------------------------------------------------------------------- - // Converts the bit pattern of a floating-point number to its signed integer representation. - BinFloat ToBinary( const ai_real & pValue) { - - // If this assertion fails, signed int is not big enough to store a float on your platform. - // Please correct the declaration of BinFloat a few lines above - but do it in a portable, - // #ifdef'd manner! - static_assert( sizeof(BinFloat) >= sizeof(ai_real), "sizeof(BinFloat) >= sizeof(ai_real)"); - - #if defined( _MSC_VER) - // If this assertion fails, Visual C++ has finally moved to ILP64. This means that this - // code has just become legacy code! Find out the current value of _MSC_VER and modify - // the #if above so it evaluates false on the current and all upcoming VC versions (or - // on the current platform, if LP64 or LLP64 are still used on other platforms). - static_assert( sizeof(BinFloat) == sizeof(ai_real), "sizeof(BinFloat) == sizeof(ai_real)"); - - // This works best on Visual C++, but other compilers have their problems with it. - const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue); - #else - // On many compilers, reinterpreting a float address as an integer causes aliasing - // problems. This is an ugly but more or less safe way of doing it. - union { - ai_real asFloat; - BinFloat asBin; - } conversion; - conversion.asBin = 0; // zero empty space in case sizeof(BinFloat) > sizeof(float) - conversion.asFloat = pValue; - const BinFloat binValue = conversion.asBin; - #endif - - // floating-point numbers are of sign-magnitude format, so find out what signed number - // representation we must convert negative values to. - // See http://en.wikipedia.org/wiki/Signed_number_representations. - - // Two's complement? - if( (-42 == (~42 + 1)) && (binValue & 0x80000000)) - return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue; - // One's complement? - else if ( (-42 == ~42) && (binValue & 0x80000000)) - return BinFloat(-0) - binValue; - // Sign-magnitude? - else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary - return binValue; - else - return binValue; - } - -} // namespace - -// ------------------------------------------------------------------------------------------------ -// Fills an array with indices of all positions identical to the given position. In opposite to -// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units. -void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition, - std::vector<unsigned int>& poResults) const -{ - // Epsilons have a huge disadvantage: they are of constant precision, while floating-point - // values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but - // if you apply it to 0.001, it is enormous. - - // The best way to overcome this is the unit in the last place (ULP). A precision of 2 ULPs - // tells us that a float does not differ more than 2 bits from the "real" value. ULPs are of - // logarithmic precision - around 1, they are 1*(2^24) and around 10000, they are 0.00125. - - // For standard C math, we can assume a precision of 0.5 ULPs according to IEEE 754. The - // incoming vertex positions might have already been transformed, probably using rather - // inaccurate SSE instructions, so we assume a tolerance of 4 ULPs to safely identify - // identical vertex positions. - static const int toleranceInULPs = 4; - // An interesting point is that the inaccuracy grows linear with the number of operations: - // multiplying to numbers, each inaccurate to four ULPs, results in an inaccuracy of four ULPs - // plus 0.5 ULPs for the multiplication. - // To compute the distance to the plane, a dot product is needed - that is a multiplication and - // an addition on each number. - static const int distanceToleranceInULPs = toleranceInULPs + 1; - // The squared distance between two 3D vectors is computed the same way, but with an additional - // subtraction. - static const int distance3DToleranceInULPs = distanceToleranceInULPs + 1; - - // Convert the plane distance to its signed integer representation so the ULPs tolerance can be - // applied. For some reason, VC won't optimize two calls of the bit pattern conversion. - const BinFloat minDistBinary = ToBinary( pPosition * mPlaneNormal) - distanceToleranceInULPs; - const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs; - - // clear the array in this strange fashion because a simple clear() would also deallocate - // the array which we want to avoid - poResults.resize( 0 ); - - // do a binary search for the minimal distance to start the iteration there - unsigned int index = (unsigned int)mPositions.size() / 2; - unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4; - while( binaryStepSize > 1) - { - // Ugly, but conditional jumps are faster with integers than with floats - if( minDistBinary > ToBinary(mPositions[index].mDistance)) - index += binaryStepSize; - else - index -= binaryStepSize; - - binaryStepSize /= 2; - } - - // depending on the direction of the last step we need to single step a bit back or forth - // to find the actual beginning element of the range - while( index > 0 && minDistBinary < ToBinary(mPositions[index].mDistance) ) - index--; - while( index < (mPositions.size() - 1) && minDistBinary > ToBinary(mPositions[index].mDistance)) - index++; - - // Now start iterating from there until the first position lays outside of the distance range. - // Add all positions inside the distance range within the tolerance to the result array - std::vector<Entry>::const_iterator it = mPositions.begin() + index; - while( ToBinary(it->mDistance) < maxDistBinary) - { - if( distance3DToleranceInULPs >= ToBinary((it->mPosition - pPosition).SquareLength())) - poResults.push_back(it->mIndex); - ++it; - if( it == mPositions.end()) - break; - } - - // that's it -} - -// ------------------------------------------------------------------------------------------------ -unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill, ai_real pRadius) const -{ - fill.resize(mPositions.size(),UINT_MAX); - ai_real dist, maxDist; - - unsigned int t=0; - const ai_real pSquared = pRadius*pRadius; - for (size_t i = 0; i < mPositions.size();) { - dist = mPositions[i].mPosition * mPlaneNormal; - maxDist = dist + pRadius; - - fill[mPositions[i].mIndex] = t; - const aiVector3D& oldpos = mPositions[i].mPosition; - for (++i; i < fill.size() && mPositions[i].mDistance < maxDist - && (mPositions[i].mPosition - oldpos).SquareLength() < pSquared; ++i) - { - fill[mPositions[i].mIndex] = t; - } - ++t; - } - -#ifdef ASSIMP_BUILD_DEBUG - - // debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1 - for (size_t i = 0; i < fill.size(); ++i) { - ai_assert(fill[i]<mPositions.size()); - } - -#endif - return t; -} diff --git a/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp deleted file mode 100644 index 2ef66a9afc..0000000000 --- a/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - - -/// @file SplitByBoneCountProcess.cpp -/// Implementation of the SplitByBoneCount postprocessing step - -// internal headers of the post-processing framework -#include "SplitByBoneCountProcess.h" -#include <assimp/postprocess.h> -#include <assimp/DefaultLogger.hpp> - -#include <limits> -#include <assimp/TinyFormatter.h> - -using namespace Assimp; -using namespace Assimp::Formatter; - -// ------------------------------------------------------------------------------------------------ -// Constructor -SplitByBoneCountProcess::SplitByBoneCountProcess() -{ - // set default, might be overridden by importer config - mMaxBoneCount = AI_SBBC_DEFAULT_MAX_BONES; -} - -// ------------------------------------------------------------------------------------------------ -// Destructor -SplitByBoneCountProcess::~SplitByBoneCountProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag. -bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const -{ - return !!(pFlags & aiProcess_SplitByBoneCount); -} - -// ------------------------------------------------------------------------------------------------ -// Updates internal properties -void SplitByBoneCountProcess::SetupProperties(const Importer* pImp) -{ - mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void SplitByBoneCountProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("SplitByBoneCountProcess begin"); - - // early out - bool isNecessary = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) - if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount ) - isNecessary = true; - - if( !isNecessary ) - { - ASSIMP_LOG_DEBUG( format() << "SplitByBoneCountProcess early-out: no meshes with more than " << mMaxBoneCount << " bones." ); - return; - } - - // we need to do something. Let's go. - mSubMeshIndices.clear(); - mSubMeshIndices.resize( pScene->mNumMeshes); - - // build a new array of meshes for the scene - std::vector<aiMesh*> meshes; - - for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) - { - aiMesh* srcMesh = pScene->mMeshes[a]; - - std::vector<aiMesh*> newMeshes; - SplitMesh( pScene->mMeshes[a], newMeshes); - - // mesh was split - if( !newMeshes.empty() ) - { - // store new meshes and indices of the new meshes - for( unsigned int b = 0; b < newMeshes.size(); ++b) - { - mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size())); - meshes.push_back( newMeshes[b]); - } - - // and destroy the source mesh. It should be completely contained inside the new submeshes - delete srcMesh; - } - else - { - // Mesh is kept unchanged - store it's new place in the mesh array - mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size())); - meshes.push_back( srcMesh); - } - } - - // rebuild the scene's mesh array - pScene->mNumMeshes = static_cast<unsigned int>(meshes.size()); - delete [] pScene->mMeshes; - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - std::copy( meshes.begin(), meshes.end(), pScene->mMeshes); - - // recurse through all nodes and translate the node's mesh indices to fit the new mesh array - UpdateNode( pScene->mRootNode); - - ASSIMP_LOG_DEBUG( format() << "SplitByBoneCountProcess end: split " << mSubMeshIndices.size() << " meshes into " << meshes.size() << " submeshes." ); -} - -// ------------------------------------------------------------------------------------------------ -// Splits the given mesh by bone count. -void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const -{ - // skip if not necessary - if( pMesh->mNumBones <= mMaxBoneCount ) - return; - - // necessary optimisation: build a list of all affecting bones for each vertex - // TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays - typedef std::pair<unsigned int, float> BoneWeight; - std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices); - for( unsigned int a = 0; a < pMesh->mNumBones; ++a) - { - const aiBone* bone = pMesh->mBones[a]; - for( unsigned int b = 0; b < bone->mNumWeights; ++b) - vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight)); - } - - unsigned int numFacesHandled = 0; - std::vector<bool> isFaceHandled( pMesh->mNumFaces, false); - while( numFacesHandled < pMesh->mNumFaces ) - { - // which bones are used in the current submesh - unsigned int numBones = 0; - std::vector<bool> isBoneUsed( pMesh->mNumBones, false); - // indices of the faces which are going to go into this submesh - std::vector<unsigned int> subMeshFaces; - subMeshFaces.reserve( pMesh->mNumFaces); - // accumulated vertex count of all the faces in this submesh - unsigned int numSubMeshVertices = 0; - // a small local array of new bones for the current face. State of all used bones for that face - // can only be updated AFTER the face is completely analysed. Thanks to imre for the fix. - std::vector<unsigned int> newBonesAtCurrentFace; - - // add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit - for( unsigned int a = 0; a < pMesh->mNumFaces; ++a) - { - // skip if the face is already stored in a submesh - if( isFaceHandled[a] ) - continue; - - const aiFace& face = pMesh->mFaces[a]; - // check every vertex if its bones would still fit into the current submesh - for( unsigned int b = 0; b < face.mNumIndices; ++b ) - { - const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]]; - for( unsigned int c = 0; c < vb.size(); ++c) - { - unsigned int boneIndex = vb[c].first; - // if the bone is already used in this submesh, it's ok - if( isBoneUsed[boneIndex] ) - continue; - - // if it's not used, yet, we would need to add it. Store its bone index - if( std::find( newBonesAtCurrentFace.begin(), newBonesAtCurrentFace.end(), boneIndex) == newBonesAtCurrentFace.end() ) - newBonesAtCurrentFace.push_back( boneIndex); - } - } - - // leave out the face if the new bones required for this face don't fit the bone count limit anymore - if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount ) - continue; - - // mark all new bones as necessary - while( !newBonesAtCurrentFace.empty() ) - { - unsigned int newIndex = newBonesAtCurrentFace.back(); - newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear() - if( isBoneUsed[newIndex] ) - continue; - - isBoneUsed[newIndex] = true; - numBones++; - } - - // store the face index and the vertex count - subMeshFaces.push_back( a); - numSubMeshVertices += face.mNumIndices; - - // remember that this face is handled - isFaceHandled[a] = true; - numFacesHandled++; - } - - // create a new mesh to hold this subset of the source mesh - aiMesh* newMesh = new aiMesh; - if( pMesh->mName.length > 0 ) - newMesh->mName.Set( format() << pMesh->mName.data << "_sub" << poNewMeshes.size()); - newMesh->mMaterialIndex = pMesh->mMaterialIndex; - newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes; - poNewMeshes.push_back( newMesh); - - // create all the arrays for this mesh if the old mesh contained them - newMesh->mNumVertices = numSubMeshVertices; - newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size()); - newMesh->mVertices = new aiVector3D[newMesh->mNumVertices]; - if( pMesh->HasNormals() ) - newMesh->mNormals = new aiVector3D[newMesh->mNumVertices]; - if( pMesh->HasTangentsAndBitangents() ) - { - newMesh->mTangents = new aiVector3D[newMesh->mNumVertices]; - newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices]; - } - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) - { - if( pMesh->HasTextureCoords( a) ) - newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices]; - newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a]; - } - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a ) - { - if( pMesh->HasVertexColors( a) ) - newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices]; - } - - // and copy over the data, generating faces with linear indices along the way - newMesh->mFaces = new aiFace[subMeshFaces.size()]; - unsigned int nvi = 0; // next vertex index - std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh - for( unsigned int a = 0; a < subMeshFaces.size(); ++a ) - { - const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]]; - aiFace& dstFace = newMesh->mFaces[a]; - dstFace.mNumIndices = srcFace.mNumIndices; - dstFace.mIndices = new unsigned int[dstFace.mNumIndices]; - - // accumulate linearly all the vertices of the source face - for( unsigned int b = 0; b < dstFace.mNumIndices; ++b ) - { - unsigned int srcIndex = srcFace.mIndices[b]; - dstFace.mIndices[b] = nvi; - previousVertexIndices[nvi] = srcIndex; - - newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex]; - if( pMesh->HasNormals() ) - newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex]; - if( pMesh->HasTangentsAndBitangents() ) - { - newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex]; - newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex]; - } - for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c ) - { - if( pMesh->HasTextureCoords( c) ) - newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex]; - } - for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c ) - { - if( pMesh->HasVertexColors( c) ) - newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex]; - } - - nvi++; - } - } - - ai_assert( nvi == numSubMeshVertices ); - - // Create the bones for the new submesh: first create the bone array - newMesh->mNumBones = 0; - newMesh->mBones = new aiBone*[numBones]; - - std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max()); - for( unsigned int a = 0; a < pMesh->mNumBones; ++a ) - { - if( !isBoneUsed[a] ) - continue; - - // create the new bone - const aiBone* srcBone = pMesh->mBones[a]; - aiBone* dstBone = new aiBone; - mappedBoneIndex[a] = newMesh->mNumBones; - newMesh->mBones[newMesh->mNumBones++] = dstBone; - dstBone->mName = srcBone->mName; - dstBone->mOffsetMatrix = srcBone->mOffsetMatrix; - dstBone->mNumWeights = 0; - } - - ai_assert( newMesh->mNumBones == numBones ); - - // iterate over all new vertices and count which bones affected its old vertex in the source mesh - for( unsigned int a = 0; a < numSubMeshVertices; ++a ) - { - unsigned int oldIndex = previousVertexIndices[a]; - const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex]; - - for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b ) - { - unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ]; - if( newBoneIndex != std::numeric_limits<unsigned int>::max() ) - newMesh->mBones[newBoneIndex]->mNumWeights++; - } - } - - // allocate all bone weight arrays accordingly - for( unsigned int a = 0; a < newMesh->mNumBones; ++a ) - { - aiBone* bone = newMesh->mBones[a]; - ai_assert( bone->mNumWeights > 0 ); - bone->mWeights = new aiVertexWeight[bone->mNumWeights]; - bone->mNumWeights = 0; // for counting up in the next step - } - - // now copy all the bone vertex weights for all the vertices which made it into the new submesh - for( unsigned int a = 0; a < numSubMeshVertices; ++a) - { - // find the source vertex for it in the source mesh - unsigned int previousIndex = previousVertexIndices[a]; - // these bones were affecting it - const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex]; - // all of the bones affecting it should be present in the new submesh, or else - // the face it comprises shouldn't be present - for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b) - { - unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ]; - ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() ); - aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights; - newMesh->mBones[newBoneIndex]->mNumWeights++; - - dstWeight->mVertexId = a; - dstWeight->mWeight = bonesOnThisVertex[b].second; - } - } - - // I have the strange feeling that this will break apart at some point in time... - } -} - -// ------------------------------------------------------------------------------------------------ -// Recursively updates the node's mesh list to account for the changed mesh list -void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const -{ - // rebuild the node's mesh index list - if( pNode->mNumMeshes > 0 ) - { - std::vector<unsigned int> newMeshList; - for( unsigned int a = 0; a < pNode->mNumMeshes; ++a) - { - unsigned int srcIndex = pNode->mMeshes[a]; - const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex]; - newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end()); - } - - delete [] pNode->mMeshes; - pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size()); - pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; - std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); - } - - // do that also recursively for all children - for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) - { - UpdateNode( pNode->mChildren[a]); - } -} diff --git a/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h deleted file mode 100644 index 6c904a9df4..0000000000 --- a/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/// @file SplitByBoneCountProcess.h -/// Defines a post processing step to split meshes with many bones into submeshes -#ifndef AI_SPLITBYBONECOUNTPROCESS_H_INC -#define AI_SPLITBYBONECOUNTPROCESS_H_INC - -#include <vector> -#include "BaseProcess.h" - -#include <assimp/mesh.h> -#include <assimp/scene.h> - -namespace Assimp -{ - - -/** Postprocessing filter to split meshes with many bones into submeshes - * so that each submesh has a certain max bone count. - * - * Applied BEFORE the JoinVertices-Step occurs. - * Returns NON-UNIQUE vertices, splits by bone count. -*/ -class SplitByBoneCountProcess : public BaseProcess -{ -public: - - SplitByBoneCountProcess(); - ~SplitByBoneCountProcess(); - -public: - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. A - * bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - bool IsActive( unsigned int pFlags) const; - - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - virtual void SetupProperties(const Importer* pImp); - -protected: - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - /// Splits the given mesh by bone count. - /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split. - /// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary. - void SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const; - - /// Recursively updates the node's mesh list to account for the changed mesh list - void UpdateNode( aiNode* pNode) const; - -public: - /// Max bone count. Splitting occurs if a mesh has more than that number of bones. - size_t mMaxBoneCount; - - /// Per mesh index: Array of indices of the new submeshes. - std::vector< std::vector<unsigned int> > mSubMeshIndices; -}; - -} // end of namespace Assimp - -#endif // !!AI_SPLITBYBONECOUNTPROCESS_H_INC diff --git a/thirdparty/assimp/code/Common/StandardShapes.cpp b/thirdparty/assimp/code/Common/StandardShapes.cpp deleted file mode 100644 index 2e5100130f..0000000000 --- a/thirdparty/assimp/code/Common/StandardShapes.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file StandardShapes.cpp - * @brief Implementation of the StandardShapes class - * - * The primitive geometry data comes from - * http://geometrictools.com/Documentation/PlatonicSolids.pdf. - */ - -#include <assimp/StandardShapes.h> -#include <assimp/StringComparison.h> -#include <stddef.h> -#include <assimp/Defines.h> -#include <assimp/mesh.h> - -namespace Assimp { - - -# define ADD_TRIANGLE(n0,n1,n2) \ - positions.push_back(n0); \ - positions.push_back(n1); \ - positions.push_back(n2); - -# define ADD_PENTAGON(n0,n1,n2,n3,n4) \ - if (polygons) \ - { \ - positions.push_back(n0); \ - positions.push_back(n1); \ - positions.push_back(n2); \ - positions.push_back(n3); \ - positions.push_back(n4); \ - } \ - else \ - { \ - ADD_TRIANGLE(n0, n1, n2) \ - ADD_TRIANGLE(n0, n2, n3) \ - ADD_TRIANGLE(n0, n3, n4) \ - } - -# define ADD_QUAD(n0,n1,n2,n3) \ - if (polygons) \ - { \ - positions.push_back(n0); \ - positions.push_back(n1); \ - positions.push_back(n2); \ - positions.push_back(n3); \ - } \ - else \ - { \ - ADD_TRIANGLE(n0, n1, n2) \ - ADD_TRIANGLE(n0, n2, n3) \ - } - - -// ------------------------------------------------------------------------------------------------ -// Fast subdivision for a mesh whose verts have a magnitude of 1 -void Subdivide(std::vector<aiVector3D>& positions) -{ - // assume this to be constant - (fixme: must be 1.0? I think so) - const ai_real fl1 = positions[0].Length(); - - unsigned int origSize = (unsigned int)positions.size(); - for (unsigned int i = 0 ; i < origSize ; i+=3) - { - aiVector3D& tv0 = positions[i]; - aiVector3D& tv1 = positions[i+1]; - aiVector3D& tv2 = positions[i+2]; - - aiVector3D a = tv0, b = tv1, c = tv2; - aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1; - aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1; - aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1; - - tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original - ADD_TRIANGLE(v1, v2, a); - ADD_TRIANGLE(v2, v3, c); - ADD_TRIANGLE(v3, v1, b); - } -} - -// ------------------------------------------------------------------------------------------------ -// Construct a mesh from given vertex positions -aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions, - unsigned int numIndices) -{ - if (positions.empty() || !numIndices) return NULL; - - // Determine which kinds of primitives the mesh consists of - aiMesh* out = new aiMesh(); - switch (numIndices) { - case 1: - out->mPrimitiveTypes = aiPrimitiveType_POINT; - break; - case 2: - out->mPrimitiveTypes = aiPrimitiveType_LINE; - break; - case 3: - out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; - break; - default: - out->mPrimitiveTypes = aiPrimitiveType_POLYGON; - break; - }; - - out->mNumFaces = (unsigned int)positions.size() / numIndices; - out->mFaces = new aiFace[out->mNumFaces]; - for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i) { - aiFace& f = out->mFaces[i]; - f.mNumIndices = numIndices; - f.mIndices = new unsigned int[numIndices]; - for (unsigned int j = 0; i < numIndices; ++i, ++a) { - f.mIndices[j] = a; - } - } - out->mNumVertices = (unsigned int)positions.size(); - out->mVertices = new aiVector3D[out->mNumVertices]; - ::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D)); - - return out; -} - -// ------------------------------------------------------------------------------------------------ -// Construct a mesh with a specific shape (callback) -aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)( - std::vector<aiVector3D>&)) -{ - std::vector<aiVector3D> temp; - unsigned num = (*GenerateFunc)(temp); - return MakeMesh(temp,num); -} - -// ------------------------------------------------------------------------------------------------ -// Construct a mesh with a specific shape (callback) -aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)( - std::vector<aiVector3D>&, bool)) -{ - std::vector<aiVector3D> temp; - unsigned num = (*GenerateFunc)(temp,true); - return MakeMesh(temp,num); -} - -// ------------------------------------------------------------------------------------------------ -// Construct a mesh with a specific shape (callback) -aiMesh* StandardShapes::MakeMesh (unsigned int num, void (*GenerateFunc)( - unsigned int,std::vector<aiVector3D>&)) -{ - std::vector<aiVector3D> temp; - (*GenerateFunc)(num,temp); - return MakeMesh(temp,3); -} - -// ------------------------------------------------------------------------------------------------ -// Build an incosahedron with points.magnitude == 1 -unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions) -{ - positions.reserve(positions.size()+60); - - const ai_real t = ( ai_real( 1.0 )+ ai_real( 2.236067977 ) ) / ai_real( 2.0 ); - const ai_real s = std::sqrt(ai_real(1.0) + t*t); - - const aiVector3D v0 = aiVector3D(t,1.0, 0.0)/s; - const aiVector3D v1 = aiVector3D(-t,1.0, 0.0)/s; - const aiVector3D v2 = aiVector3D(t,-1.0, 0.0)/s; - const aiVector3D v3 = aiVector3D(-t,-1.0, 0.0)/s; - const aiVector3D v4 = aiVector3D(1.0, 0.0, t)/s; - const aiVector3D v5 = aiVector3D(1.0, 0.0,-t)/s; - const aiVector3D v6 = aiVector3D(-1.0, 0.0,t)/s; - const aiVector3D v7 = aiVector3D(-1.0, 0.0,-t)/s; - const aiVector3D v8 = aiVector3D(0.0, t, 1.0)/s; - const aiVector3D v9 = aiVector3D(0.0,-t, 1.0)/s; - const aiVector3D v10 = aiVector3D(0.0, t,-1.0)/s; - const aiVector3D v11 = aiVector3D(0.0,-t,-1.0)/s; - - ADD_TRIANGLE(v0,v8,v4); - ADD_TRIANGLE(v0,v5,v10); - ADD_TRIANGLE(v2,v4,v9); - ADD_TRIANGLE(v2,v11,v5); - - ADD_TRIANGLE(v1,v6,v8); - ADD_TRIANGLE(v1,v10,v7); - ADD_TRIANGLE(v3,v9,v6); - ADD_TRIANGLE(v3,v7,v11); - - ADD_TRIANGLE(v0,v10,v8); - ADD_TRIANGLE(v1,v8,v10); - ADD_TRIANGLE(v2,v9,v11); - ADD_TRIANGLE(v3,v11,v9); - - ADD_TRIANGLE(v4,v2,v0); - ADD_TRIANGLE(v5,v0,v2); - ADD_TRIANGLE(v6,v1,v3); - ADD_TRIANGLE(v7,v3,v1); - - ADD_TRIANGLE(v8,v6,v4); - ADD_TRIANGLE(v9,v4,v6); - ADD_TRIANGLE(v10,v5,v7); - ADD_TRIANGLE(v11,v7,v5); - return 3; -} - -// ------------------------------------------------------------------------------------------------ -// Build a dodecahedron with points.magnitude == 1 -unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions, - bool polygons /*= false*/) -{ - positions.reserve(positions.size()+108); - - const ai_real a = ai_real( 1.0 ) / ai_real(1.7320508); - const ai_real b = std::sqrt(( ai_real( 3.0 )- ai_real( 2.23606797))/ ai_real( 6.0) ); - const ai_real c = std::sqrt(( ai_real( 3.0 )+ ai_real( 2.23606797f))/ ai_real( 6.0) ); - - const aiVector3D v0 = aiVector3D(a,a,a); - const aiVector3D v1 = aiVector3D(a,a,-a); - const aiVector3D v2 = aiVector3D(a,-a,a); - const aiVector3D v3 = aiVector3D(a,-a,-a); - const aiVector3D v4 = aiVector3D(-a,a,a); - const aiVector3D v5 = aiVector3D(-a,a,-a); - const aiVector3D v6 = aiVector3D(-a,-a,a); - const aiVector3D v7 = aiVector3D(-a,-a,-a); - const aiVector3D v8 = aiVector3D(b,c,0.0); - const aiVector3D v9 = aiVector3D(-b,c,0.0); - const aiVector3D v10 = aiVector3D(b,-c,0.0); - const aiVector3D v11 = aiVector3D(-b,-c,0.0); - const aiVector3D v12 = aiVector3D(c, 0.0, b); - const aiVector3D v13 = aiVector3D(c, 0.0, -b); - const aiVector3D v14 = aiVector3D(-c, 0.0, b); - const aiVector3D v15 = aiVector3D(-c, 0.0, -b); - const aiVector3D v16 = aiVector3D(0.0, b, c); - const aiVector3D v17 = aiVector3D(0.0, -b, c); - const aiVector3D v18 = aiVector3D(0.0, b, -c); - const aiVector3D v19 = aiVector3D(0.0, -b, -c); - - ADD_PENTAGON(v0, v8, v9, v4, v16); - ADD_PENTAGON(v0, v12, v13, v1, v8); - ADD_PENTAGON(v0, v16, v17, v2, v12); - ADD_PENTAGON(v8, v1, v18, v5, v9); - ADD_PENTAGON(v12, v2, v10, v3, v13); - ADD_PENTAGON(v16, v4, v14, v6, v17); - ADD_PENTAGON(v9, v5, v15, v14, v4); - - ADD_PENTAGON(v6, v11, v10, v2, v17); - ADD_PENTAGON(v3, v19, v18, v1, v13); - ADD_PENTAGON(v7, v15, v5, v18, v19); - ADD_PENTAGON(v7, v11, v6, v14, v15); - ADD_PENTAGON(v7, v19, v3, v10, v11); - return (polygons ? 5 : 3); -} - -// ------------------------------------------------------------------------------------------------ -// Build an octahedron with points.magnitude == 1 -unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions) -{ - positions.reserve(positions.size()+24); - - const aiVector3D v0 = aiVector3D(1.0, 0.0, 0.0) ; - const aiVector3D v1 = aiVector3D(-1.0, 0.0, 0.0); - const aiVector3D v2 = aiVector3D(0.0, 1.0, 0.0); - const aiVector3D v3 = aiVector3D(0.0, -1.0, 0.0); - const aiVector3D v4 = aiVector3D(0.0, 0.0, 1.0); - const aiVector3D v5 = aiVector3D(0.0, 0.0, -1.0); - - ADD_TRIANGLE(v4,v0,v2); - ADD_TRIANGLE(v4,v2,v1); - ADD_TRIANGLE(v4,v1,v3); - ADD_TRIANGLE(v4,v3,v0); - - ADD_TRIANGLE(v5,v2,v0); - ADD_TRIANGLE(v5,v1,v2); - ADD_TRIANGLE(v5,v3,v1); - ADD_TRIANGLE(v5,v0,v3); - return 3; -} - -// ------------------------------------------------------------------------------------------------ -// Build a tetrahedron with points.magnitude == 1 -unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions) -{ - positions.reserve(positions.size()+9); - - const ai_real invThree = ai_real( 1.0 ) / ai_real( 3.0 ); - const ai_real a = ai_real( 1.41421 ) * invThree; - const ai_real b = ai_real( 2.4494 ) * invThree; - - const aiVector3D v0 = aiVector3D(0.0,0.0,1.0); - const aiVector3D v1 = aiVector3D(2*a,0,-invThree ); - const aiVector3D v2 = aiVector3D(-a,b,-invThree ); - const aiVector3D v3 = aiVector3D(-a,-b,-invThree ); - - ADD_TRIANGLE(v0,v1,v2); - ADD_TRIANGLE(v0,v2,v3); - ADD_TRIANGLE(v0,v3,v1); - ADD_TRIANGLE(v1,v3,v2); - return 3; -} - -// ------------------------------------------------------------------------------------------------ -// Build a hexahedron with points.magnitude == 1 -unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions, - bool polygons /*= false*/) -{ - positions.reserve(positions.size()+36); - const ai_real length = ai_real(1.0)/ai_real(1.73205080); - - const aiVector3D v0 = aiVector3D(-1.0,-1.0,-1.0)*length; - const aiVector3D v1 = aiVector3D(1.0,-1.0,-1.0)*length; - const aiVector3D v2 = aiVector3D(1.0,1.0,-1.0)*length; - const aiVector3D v3 = aiVector3D(-1.0,1.0,-1.0)*length; - const aiVector3D v4 = aiVector3D(-1.0,-1.0,1.0)*length; - const aiVector3D v5 = aiVector3D(1.0,-1.0,1.0)*length; - const aiVector3D v6 = aiVector3D(1.0,1.0,1.0)*length; - const aiVector3D v7 = aiVector3D(-1.0,1.0,1.0)*length; - - ADD_QUAD(v0,v3,v2,v1); - ADD_QUAD(v0,v1,v5,v4); - ADD_QUAD(v0,v4,v7,v3); - ADD_QUAD(v6,v5,v1,v2); - ADD_QUAD(v6,v2,v3,v7); - ADD_QUAD(v6,v7,v4,v5); - return (polygons ? 4 : 3); -} - -// Cleanup ... -#undef ADD_TRIANGLE -#undef ADD_QUAD -#undef ADD_PENTAGON - -// ------------------------------------------------------------------------------------------------ -// Create a subdivision sphere -void StandardShapes::MakeSphere(unsigned int tess, - std::vector<aiVector3D>& positions) -{ - // Reserve enough storage. Every subdivision - // splits each triangle in 4, the icosahedron consists of 60 verts - positions.reserve(positions.size()+60 * integer_pow(4, tess)); - - // Construct an icosahedron to start with - MakeIcosahedron(positions); - - // ... and subdivide it until the requested output - // tessellation is reached - for (unsigned int i = 0; i<tess;++i) - Subdivide(positions); -} - -// ------------------------------------------------------------------------------------------------ -// Build a cone -void StandardShapes::MakeCone(ai_real height,ai_real radius1, - ai_real radius2,unsigned int tess, - std::vector<aiVector3D>& positions,bool bOpen /*= false */) -{ - // Sorry, a cone with less than 3 segments makes ABSOLUTELY NO SENSE - if (tess < 3 || !height) - return; - - size_t old = positions.size(); - - // No negative radii - radius1 = std::fabs(radius1); - radius2 = std::fabs(radius2); - - ai_real halfHeight = height / ai_real(2.0); - - // radius1 is always the smaller one - if (radius2 > radius1) - { - std::swap(radius2,radius1); - halfHeight = -halfHeight; - } - else old = SIZE_MAX; - - // Use a large epsilon to check whether the cone is pointy - if (radius1 < (radius2-radius1)*10e-3)radius1 = 0.0; - - // We will need 3*2 verts per segment + 3*2 verts per segment - // if the cone is closed - const unsigned int mem = tess*6 + (!bOpen ? tess*3 * (radius1 ? 2 : 1) : 0); - positions.reserve(positions.size () + mem); - - // Now construct all segments - const ai_real angle_delta = (ai_real)AI_MATH_TWO_PI / tess; - const ai_real angle_max = (ai_real)AI_MATH_TWO_PI; - - ai_real s = 1.0; // std::cos(angle == 0); - ai_real t = 0.0; // std::sin(angle == 0); - - for (ai_real angle = 0.0; angle < angle_max; ) - { - const aiVector3D v1 = aiVector3D (s * radius1, -halfHeight, t * radius1 ); - const aiVector3D v2 = aiVector3D (s * radius2, halfHeight, t * radius2 ); - - const ai_real next = angle + angle_delta; - ai_real s2 = std::cos(next); - ai_real t2 = std::sin(next); - - const aiVector3D v3 = aiVector3D (s2 * radius2, halfHeight, t2 * radius2 ); - const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 ); - - positions.push_back(v1); - positions.push_back(v2); - positions.push_back(v3); - positions.push_back(v4); - positions.push_back(v1); - positions.push_back(v3); - - if (!bOpen) - { - // generate the end 'cap' - positions.push_back(aiVector3D(s * radius2, halfHeight, t * radius2 )); - positions.push_back(aiVector3D(s2 * radius2, halfHeight, t2 * radius2 )); - positions.push_back(aiVector3D(0.0, halfHeight, 0.0)); - - - if (radius1) - { - // generate the other end 'cap' - positions.push_back(aiVector3D(s * radius1, -halfHeight, t * radius1 )); - positions.push_back(aiVector3D(s2 * radius1, -halfHeight, t2 * radius1 )); - positions.push_back(aiVector3D(0.0, -halfHeight, 0.0)); - - } - } - s = s2; - t = t2; - angle = next; - } - - // Need to flip face order? - if ( SIZE_MAX != old ) { - for (size_t p = old; p < positions.size();p += 3) { - std::swap(positions[p],positions[p+1]); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Build a circle -void StandardShapes::MakeCircle(ai_real radius, unsigned int tess, - std::vector<aiVector3D>& positions) -{ - // Sorry, a circle with less than 3 segments makes ABSOLUTELY NO SENSE - if (tess < 3 || !radius) - return; - - radius = std::fabs(radius); - - // We will need 3 vertices per segment - positions.reserve(positions.size()+tess*3); - - const ai_real angle_delta = (ai_real)AI_MATH_TWO_PI / tess; - const ai_real angle_max = (ai_real)AI_MATH_TWO_PI; - - ai_real s = 1.0; // std::cos(angle == 0); - ai_real t = 0.0; // std::sin(angle == 0); - - for (ai_real angle = 0.0; angle < angle_max; ) - { - positions.push_back(aiVector3D(s * radius,0.0,t * radius)); - angle += angle_delta; - s = std::cos(angle); - t = std::sin(angle); - positions.push_back(aiVector3D(s * radius,0.0,t * radius)); - - positions.push_back(aiVector3D(0.0,0.0,0.0)); - } -} - -} // ! Assimp diff --git a/thirdparty/assimp/code/Common/StdOStreamLogStream.h b/thirdparty/assimp/code/Common/StdOStreamLogStream.h deleted file mode 100644 index 893e261a2b..0000000000 --- a/thirdparty/assimp/code/Common/StdOStreamLogStream.h +++ /dev/null @@ -1,101 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file StdOStreamLogStream.h -* @brief Implementation of StdOStreamLogStream -*/ - -#ifndef AI_STROSTREAMLOGSTREAM_H_INC -#define AI_STROSTREAMLOGSTREAM_H_INC - -#include <assimp/LogStream.hpp> -#include <ostream> - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** @class StdOStreamLogStream - * @brief Logs into a std::ostream - */ -class StdOStreamLogStream : public LogStream { -public: - /** @brief Construction from an existing std::ostream - * @param _ostream Output stream to be used - */ - explicit StdOStreamLogStream(std::ostream& _ostream); - - /** @brief Destructor */ - ~StdOStreamLogStream(); - - /** @brief Writer */ - void write(const char* message); - -private: - std::ostream& mOstream; -}; - -// --------------------------------------------------------------------------- -// Default constructor -inline StdOStreamLogStream::StdOStreamLogStream(std::ostream& _ostream) -: mOstream (_ostream){ - // empty -} - -// --------------------------------------------------------------------------- -// Default constructor -inline StdOStreamLogStream::~StdOStreamLogStream() { - // empty -} - -// --------------------------------------------------------------------------- -// Write method -inline void StdOStreamLogStream::write(const char* message) { - mOstream << message; - mOstream.flush(); -} - -// --------------------------------------------------------------------------- - -} // Namespace Assimp - -#endif // guard diff --git a/thirdparty/assimp/code/Common/Subdivision.cpp b/thirdparty/assimp/code/Common/Subdivision.cpp deleted file mode 100644 index 60c54939f5..0000000000 --- a/thirdparty/assimp/code/Common/Subdivision.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#include <assimp/Subdivision.h> -#include <assimp/SceneCombiner.h> -#include <assimp/SpatialSort.h> -#include <assimp/Vertex.h> -#include <assimp/ai_assert.h> - -#include "PostProcessing/ProcessHelper.h" - -#include <stdio.h> - -using namespace Assimp; -void mydummy() {} - -// ------------------------------------------------------------------------------------------------ -/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The - * implementation is basing on recursive refinement. Directly evaluating the result is also - * possible and much quicker, but it depends on lengthy matrix lookup tables. */ -// ------------------------------------------------------------------------------------------------ -class CatmullClarkSubdivider : public Subdivider { -public: - void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input); - void Subdivide (aiMesh** smesh, size_t nmesh, - aiMesh** out, unsigned int num, bool discard_input); - - // --------------------------------------------------------------------------- - /** Intermediate description of an edge between two corners of a polygon*/ - // --------------------------------------------------------------------------- - struct Edge - { - Edge() - : ref(0) - {} - Vertex edge_point, midpoint; - unsigned int ref; - }; - - typedef std::vector<unsigned int> UIntVector; - typedef std::map<uint64_t,Edge> EdgeMap; - - // --------------------------------------------------------------------------- - // Hashing function to derive an index into an #EdgeMap from two given - // 'unsigned int' vertex coordinates (!!distinct coordinates - same - // vertex position == same index!!). - // NOTE - this leads to rare hash collisions if a) sizeof(unsigned int)>4 - // and (id[0]>2^32-1 or id[0]>2^32-1). - // MAKE_EDGE_HASH() uses temporaries, so INIT_EDGE_HASH() needs to be put - // at the head of every function which is about to use MAKE_EDGE_HASH(). - // Reason is that the hash is that hash construction needs to hold the - // invariant id0<id1 to identify an edge - else two hashes would refer - // to the same edge. - // --------------------------------------------------------------------------- -#define MAKE_EDGE_HASH(id0,id1) (eh_tmp0__=id0,eh_tmp1__=id1,\ - (eh_tmp0__<eh_tmp1__?std::swap(eh_tmp0__,eh_tmp1__):mydummy()),(uint64_t)eh_tmp0__^((uint64_t)eh_tmp1__<<32u)) - - -#define INIT_EDGE_HASH_TEMPORARIES()\ - unsigned int eh_tmp0__, eh_tmp1__; - -private: - void InternSubdivide (const aiMesh* const * smesh, - size_t nmesh,aiMesh** out, unsigned int num); -}; - - -// ------------------------------------------------------------------------------------------------ -// Construct a subdivider of a specific type -Subdivider* Subdivider::Create (Algorithm algo) -{ - switch (algo) - { - case CATMULL_CLARKE: - return new CatmullClarkSubdivider(); - }; - - ai_assert(false); - return NULL; // shouldn't happen -} - -// ------------------------------------------------------------------------------------------------ -// Call the Catmull Clark subdivision algorithm for one mesh -void CatmullClarkSubdivider::Subdivide ( - aiMesh* mesh, - aiMesh*& out, - unsigned int num, - bool discard_input - ) -{ - ai_assert(mesh != out); - - Subdivide(&mesh,1,&out,num,discard_input); -} - -// ------------------------------------------------------------------------------------------------ -// Call the Catmull Clark subdivision algorithm for multiple meshes -void CatmullClarkSubdivider::Subdivide ( - aiMesh** smesh, - size_t nmesh, - aiMesh** out, - unsigned int num, - bool discard_input - ) -{ - ai_assert( NULL != smesh ); - ai_assert( NULL != out ); - - // course, both regions may not overlap - ai_assert(smesh<out || smesh+nmesh>out+nmesh); - if (!num) { - // No subdivision at all. Need to copy all the meshes .. argh. - if (discard_input) { - for (size_t s = 0; s < nmesh; ++s) { - out[s] = smesh[s]; - smesh[s] = NULL; - } - } - else { - for (size_t s = 0; s < nmesh; ++s) { - SceneCombiner::Copy(out+s,smesh[s]); - } - } - return; - } - - std::vector<aiMesh*> inmeshes; - std::vector<aiMesh*> outmeshes; - std::vector<unsigned int> maptbl; - - inmeshes.reserve(nmesh); - outmeshes.reserve(nmesh); - maptbl.reserve(nmesh); - - // Remove pure line and point meshes from the working set to reduce the - // number of edge cases the subdivider is forced to deal with. Line and - // point meshes are simply passed through. - for (size_t s = 0; s < nmesh; ++s) { - aiMesh* i = smesh[s]; - // FIX - mPrimitiveTypes might not yet be initialized - if (i->mPrimitiveTypes && (i->mPrimitiveTypes & (aiPrimitiveType_LINE|aiPrimitiveType_POINT))==i->mPrimitiveTypes) { - ASSIMP_LOG_DEBUG("Catmull-Clark Subdivider: Skipping pure line/point mesh"); - - if (discard_input) { - out[s] = i; - smesh[s] = NULL; - } - else { - SceneCombiner::Copy(out+s,i); - } - continue; - } - - outmeshes.push_back(NULL);inmeshes.push_back(i); - maptbl.push_back(static_cast<unsigned int>(s)); - } - - // Do the actual subdivision on the preallocated storage. InternSubdivide - // *always* assumes that enough storage is available, it does not bother - // checking any ranges. - ai_assert(inmeshes.size()==outmeshes.size()&&inmeshes.size()==maptbl.size()); - if (inmeshes.empty()) { - ASSIMP_LOG_WARN("Catmull-Clark Subdivider: Pure point/line scene, I can't do anything"); - return; - } - InternSubdivide(&inmeshes.front(),inmeshes.size(),&outmeshes.front(),num); - for (unsigned int i = 0; i < maptbl.size(); ++i) { - ai_assert(nullptr != outmeshes[i]); - out[maptbl[i]] = outmeshes[i]; - } - - if (discard_input) { - for (size_t s = 0; s < nmesh; ++s) { - delete smesh[s]; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Note - this is an implementation of the standard (recursive) Cm-Cl algorithm without further -// optimizations (except we're using some nice LUTs). A description of the algorithm can be found -// here: http://en.wikipedia.org/wiki/Catmull-Clark_subdivision_surface -// -// The code is mostly O(n), however parts are O(nlogn) which is therefore the algorithm's -// expected total runtime complexity. The implementation is able to work in-place on the same -// mesh arrays. Calling #InternSubdivide() directly is not encouraged. The code can operate -// in-place unless 'smesh' and 'out' are equal (no strange overlaps or reorderings). -// Previous data is replaced/deleted then. -// ------------------------------------------------------------------------------------------------ -void CatmullClarkSubdivider::InternSubdivide ( - const aiMesh* const * smesh, - size_t nmesh, - aiMesh** out, - unsigned int num - ) -{ - ai_assert(NULL != smesh && NULL != out); - INIT_EDGE_HASH_TEMPORARIES(); - - // no subdivision requested or end of recursive refinement - if (!num) { - return; - } - - UIntVector maptbl; - SpatialSort spatial; - - // --------------------------------------------------------------------- - // 0. Offset table to index all meshes continuously, generate a spatially - // sorted representation of all vertices in all meshes. - // --------------------------------------------------------------------- - typedef std::pair<unsigned int,unsigned int> IntPair; - std::vector<IntPair> moffsets(nmesh); - unsigned int totfaces = 0, totvert = 0; - for (size_t t = 0; t < nmesh; ++t) { - const aiMesh* mesh = smesh[t]; - - spatial.Append(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D),false); - moffsets[t] = IntPair(totfaces,totvert); - - totfaces += mesh->mNumFaces; - totvert += mesh->mNumVertices; - } - - spatial.Finalize(); - const unsigned int num_unique = spatial.GenerateMappingTable(maptbl,ComputePositionEpsilon(smesh,nmesh)); - - -#define FLATTEN_VERTEX_IDX(mesh_idx, vert_idx) (moffsets[mesh_idx].second+vert_idx) -#define FLATTEN_FACE_IDX(mesh_idx, face_idx) (moffsets[mesh_idx].first+face_idx) - - // --------------------------------------------------------------------- - // 1. Compute the centroid point for all faces - // --------------------------------------------------------------------- - std::vector<Vertex> centroids(totfaces); - unsigned int nfacesout = 0; - for (size_t t = 0, n = 0; t < nmesh; ++t) { - const aiMesh* mesh = smesh[t]; - for (unsigned int i = 0; i < mesh->mNumFaces;++i,++n) - { - const aiFace& face = mesh->mFaces[i]; - Vertex& c = centroids[n]; - - for (unsigned int a = 0; a < face.mNumIndices;++a) { - c += Vertex(mesh,face.mIndices[a]); - } - - c /= static_cast<float>(face.mNumIndices); - nfacesout += face.mNumIndices; - } - } - - { - // we want edges to go away before the recursive calls so begin a new scope - EdgeMap edges; - - // --------------------------------------------------------------------- - // 2. Set each edge point to be the average of all neighbouring - // face points and original points. Every edge exists twice - // if there is a neighboring face. - // --------------------------------------------------------------------- - for (size_t t = 0; t < nmesh; ++t) { - const aiMesh* mesh = smesh[t]; - - for (unsigned int i = 0; i < mesh->mNumFaces;++i) { - const aiFace& face = mesh->mFaces[i]; - - for (unsigned int p =0; p< face.mNumIndices; ++p) { - const unsigned int id[] = { - face.mIndices[p], - face.mIndices[p==face.mNumIndices-1?0:p+1] - }; - const unsigned int mp[] = { - maptbl[FLATTEN_VERTEX_IDX(t,id[0])], - maptbl[FLATTEN_VERTEX_IDX(t,id[1])] - }; - - Edge& e = edges[MAKE_EDGE_HASH(mp[0],mp[1])]; - e.ref++; - if (e.ref<=2) { - if (e.ref==1) { // original points (end points) - add only once - e.edge_point = e.midpoint = Vertex(mesh,id[0])+Vertex(mesh,id[1]); - e.midpoint *= 0.5f; - } - e.edge_point += centroids[FLATTEN_FACE_IDX(t,i)]; - } - } - } - } - - // --------------------------------------------------------------------- - // 3. Normalize edge points - // --------------------------------------------------------------------- - {unsigned int bad_cnt = 0; - for (EdgeMap::iterator it = edges.begin(); it != edges.end(); ++it) { - if ((*it).second.ref < 2) { - ai_assert((*it).second.ref); - ++bad_cnt; - } - (*it).second.edge_point *= 1.f/((*it).second.ref+2.f); - } - - if (bad_cnt) { - // Report the number of bad edges. bad edges are referenced by less than two - // faces in the mesh. They occur at outer model boundaries in non-closed - // shapes. - ASSIMP_LOG_DEBUG_F("Catmull-Clark Subdivider: got ", bad_cnt, " bad edges touching only one face (totally ", - static_cast<unsigned int>(edges.size()), " edges). "); - }} - - // --------------------------------------------------------------------- - // 4. Compute a vertex-face adjacency table. We can't reuse the code - // from VertexTriangleAdjacency because we need the table for multiple - // meshes and out vertex indices need to be mapped to distinct values - // first. - // --------------------------------------------------------------------- - UIntVector faceadjac(nfacesout), cntadjfac(maptbl.size(),0), ofsadjvec(maptbl.size()+1,0); { - for (size_t t = 0; t < nmesh; ++t) { - const aiMesh* const minp = smesh[t]; - for (unsigned int i = 0; i < minp->mNumFaces; ++i) { - - const aiFace& f = minp->mFaces[i]; - for (unsigned int n = 0; n < f.mNumIndices; ++n) { - ++cntadjfac[maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]]; - } - } - } - unsigned int cur = 0; - for (size_t i = 0; i < cntadjfac.size(); ++i) { - ofsadjvec[i+1] = cur; - cur += cntadjfac[i]; - } - for (size_t t = 0; t < nmesh; ++t) { - const aiMesh* const minp = smesh[t]; - for (unsigned int i = 0; i < minp->mNumFaces; ++i) { - - const aiFace& f = minp->mFaces[i]; - for (unsigned int n = 0; n < f.mNumIndices; ++n) { - faceadjac[ofsadjvec[1+maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]]++] = FLATTEN_FACE_IDX(t,i); - } - } - } - - // check the other way round for consistency -#ifdef ASSIMP_BUILD_DEBUG - - for (size_t t = 0; t < ofsadjvec.size()-1; ++t) { - for (unsigned int m = 0; m < cntadjfac[t]; ++m) { - const unsigned int fidx = faceadjac[ofsadjvec[t]+m]; - ai_assert(fidx < totfaces); - for (size_t n = 1; n < nmesh; ++n) { - - if (moffsets[n].first > fidx) { - const aiMesh* msh = smesh[--n]; - const aiFace& f = msh->mFaces[fidx-moffsets[n].first]; - - bool haveit = false; - for (unsigned int i = 0; i < f.mNumIndices; ++i) { - if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) { - haveit = true; - break; - } - } - ai_assert(haveit); - if (!haveit) { - ASSIMP_LOG_DEBUG("Catmull-Clark Subdivider: Index not used"); - } - break; - } - } - } - } - -#endif - } - -#define GET_ADJACENT_FACES_AND_CNT(vidx,fstartout,numout) \ - fstartout = &faceadjac[ofsadjvec[vidx]], numout = cntadjfac[vidx] - - typedef std::pair<bool,Vertex> TouchedOVertex; - std::vector<TouchedOVertex > new_points(num_unique,TouchedOVertex(false,Vertex())); - // --------------------------------------------------------------------- - // 5. Spawn a quad from each face point to the corresponding edge points - // the original points being the fourth quad points. - // --------------------------------------------------------------------- - for (size_t t = 0; t < nmesh; ++t) { - const aiMesh* const minp = smesh[t]; - aiMesh* const mout = out[t] = new aiMesh(); - - for (unsigned int a = 0; a < minp->mNumFaces; ++a) { - mout->mNumFaces += minp->mFaces[a].mNumIndices; - } - - // We need random access to the old face buffer, so reuse is not possible. - mout->mFaces = new aiFace[mout->mNumFaces]; - - mout->mNumVertices = mout->mNumFaces*4; - mout->mVertices = new aiVector3D[mout->mNumVertices]; - - // quads only, keep material index - mout->mPrimitiveTypes = aiPrimitiveType_POLYGON; - mout->mMaterialIndex = minp->mMaterialIndex; - - if (minp->HasNormals()) { - mout->mNormals = new aiVector3D[mout->mNumVertices]; - } - - if (minp->HasTangentsAndBitangents()) { - mout->mTangents = new aiVector3D[mout->mNumVertices]; - mout->mBitangents = new aiVector3D[mout->mNumVertices]; - } - - for(unsigned int i = 0; minp->HasTextureCoords(i); ++i) { - mout->mTextureCoords[i] = new aiVector3D[mout->mNumVertices]; - mout->mNumUVComponents[i] = minp->mNumUVComponents[i]; - } - - for(unsigned int i = 0; minp->HasVertexColors(i); ++i) { - mout->mColors[i] = new aiColor4D[mout->mNumVertices]; - } - - mout->mNumVertices = mout->mNumFaces<<2u; - for (unsigned int i = 0, v = 0, n = 0; i < minp->mNumFaces;++i) { - - const aiFace& face = minp->mFaces[i]; - for (unsigned int a = 0; a < face.mNumIndices;++a) { - - // Get a clean new face. - aiFace& faceOut = mout->mFaces[n++]; - faceOut.mIndices = new unsigned int [faceOut.mNumIndices = 4]; - - // Spawn a new quadrilateral (ccw winding) for this original point between: - // a) face centroid - centroids[FLATTEN_FACE_IDX(t,i)].SortBack(mout,faceOut.mIndices[0]=v++); - - // b) adjacent edge on the left, seen from the centroid - const Edge& e0 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])], - maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a==face.mNumIndices-1?0:a+1]) - ])]; // fixme: replace with mod face.mNumIndices? - - // c) adjacent edge on the right, seen from the centroid - const Edge& e1 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])], - maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[!a?face.mNumIndices-1:a-1]) - ])]; // fixme: replace with mod face.mNumIndices? - - e0.edge_point.SortBack(mout,faceOut.mIndices[3]=v++); - e1.edge_point.SortBack(mout,faceOut.mIndices[1]=v++); - - // d= original point P with distinct index i - // F := 0 - // R := 0 - // n := 0 - // for each face f containing i - // F := F+ centroid of f - // R := R+ midpoint of edge of f from i to i+1 - // n := n+1 - // - // (F+2R+(n-3)P)/n - const unsigned int org = maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])]; - TouchedOVertex& ov = new_points[org]; - - if (!ov.first) { - ov.first = true; - - const unsigned int* adj; unsigned int cnt; - GET_ADJACENT_FACES_AND_CNT(org,adj,cnt); - - if (cnt < 3) { - ov.second = Vertex(minp,face.mIndices[a]); - } - else { - - Vertex F,R; - for (unsigned int o = 0; o < cnt; ++o) { - ai_assert(adj[o] < totfaces); - F += centroids[adj[o]]; - - // adj[0] is a global face index - search the face in the mesh list - const aiMesh* mp = NULL; - size_t nidx; - - if (adj[o] < moffsets[0].first) { - mp = smesh[nidx=0]; - } - else { - for (nidx = 1; nidx<= nmesh; ++nidx) { - if (nidx == nmesh ||moffsets[nidx].first > adj[o]) { - mp = smesh[--nidx]; - break; - } - } - } - - ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces); - const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first]; - bool haveit = false; - - // find our original point in the face - for (unsigned int m = 0; m < f.mNumIndices; ++m) { - if (maptbl[FLATTEN_VERTEX_IDX(nidx,f.mIndices[m])] == org) { - - // add *both* edges. this way, we can be sure that we add - // *all* adjacent edges to R. In a closed shape, every - // edge is added twice - so we simply leave out the - // factor 2.f in the amove formula and get the right - // result. - - const Edge& c0 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX( - nidx,f.mIndices[!m?f.mNumIndices-1:m-1])])]; - // fixme: replace with mod face.mNumIndices? - - const Edge& c1 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX( - nidx,f.mIndices[m==f.mNumIndices-1?0:m+1])])]; - // fixme: replace with mod face.mNumIndices? - R += c0.midpoint+c1.midpoint; - - haveit = true; - break; - } - } - - // this invariant *must* hold if the vertex-to-face adjacency table is valid - ai_assert(haveit); - if ( !haveit ) { - ASSIMP_LOG_WARN( "OBJ: no name for material library specified." ); - } - } - - const float div = static_cast<float>(cnt), divsq = 1.f/(div*div); - ov.second = Vertex(minp,face.mIndices[a])*((div-3.f) / div) + R*divsq + F*divsq; - } - } - ov.second.SortBack(mout,faceOut.mIndices[2]=v++); - } - } - } - } // end of scope for edges, freeing its memory - - // --------------------------------------------------------------------- - // 7. Apply the next subdivision step. - // --------------------------------------------------------------------- - if (num != 1) { - std::vector<aiMesh*> tmp(nmesh); - InternSubdivide (out,nmesh,&tmp.front(),num-1); - for (size_t i = 0; i < nmesh; ++i) { - delete out[i]; - out[i] = tmp[i]; - } - } -} diff --git a/thirdparty/assimp/code/Common/TargetAnimation.cpp b/thirdparty/assimp/code/Common/TargetAnimation.cpp deleted file mode 100644 index b8062499ff..0000000000 --- a/thirdparty/assimp/code/Common/TargetAnimation.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#include "TargetAnimation.h" -#include <algorithm> -#include <assimp/ai_assert.h> - -using namespace Assimp; - - -// ------------------------------------------------------------------------------------------------ -KeyIterator::KeyIterator(const std::vector<aiVectorKey>* _objPos, - const std::vector<aiVectorKey>* _targetObjPos, - const aiVector3D* defaultObjectPos /*= NULL*/, - const aiVector3D* defaultTargetPos /*= NULL*/) - - : reachedEnd (false) - , curTime (-1.) - , objPos (_objPos) - , targetObjPos (_targetObjPos) - , nextObjPos (0) - , nextTargetObjPos(0) -{ - // Generate default transformation tracks if necessary - if (!objPos || objPos->empty()) - { - defaultObjPos.resize(1); - defaultObjPos.front().mTime = 10e10; - - if (defaultObjectPos) - defaultObjPos.front().mValue = *defaultObjectPos; - - objPos = & defaultObjPos; - } - if (!targetObjPos || targetObjPos->empty()) - { - defaultTargetObjPos.resize(1); - defaultTargetObjPos.front().mTime = 10e10; - - if (defaultTargetPos) - defaultTargetObjPos.front().mValue = *defaultTargetPos; - - targetObjPos = & defaultTargetObjPos; - } -} - -// ------------------------------------------------------------------------------------------------ -template <class T> -inline T Interpolate(const T& one, const T& two, ai_real val) -{ - return one + (two-one)*val; -} - -// ------------------------------------------------------------------------------------------------ -void KeyIterator::operator ++() -{ - // If we are already at the end of all keyframes, return - if (reachedEnd) { - return; - } - - // Now search in all arrays for the time value closest - // to our current position on the time line - double d0,d1; - - d0 = objPos->at ( std::min ( nextObjPos, static_cast<unsigned int>(objPos->size()-1)) ).mTime; - d1 = targetObjPos->at( std::min ( nextTargetObjPos, static_cast<unsigned int>(targetObjPos->size()-1)) ).mTime; - - // Easiest case - all are identical. In this - // case we don't need to interpolate so we can - // return earlier - if ( d0 == d1 ) - { - curTime = d0; - curPosition = objPos->at(nextObjPos).mValue; - curTargetPosition = targetObjPos->at(nextTargetObjPos).mValue; - - // increment counters - if (objPos->size() != nextObjPos-1) - ++nextObjPos; - - if (targetObjPos->size() != nextTargetObjPos-1) - ++nextTargetObjPos; - } - - // An object position key is closest to us - else if (d0 < d1) - { - curTime = d0; - - // interpolate the other - if (1 == targetObjPos->size() || !nextTargetObjPos) { - curTargetPosition = targetObjPos->at(0).mValue; - } - else - { - const aiVectorKey& last = targetObjPos->at(nextTargetObjPos); - const aiVectorKey& first = targetObjPos->at(nextTargetObjPos-1); - - curTargetPosition = Interpolate(first.mValue, last.mValue, (ai_real) ( - (curTime-first.mTime) / (last.mTime-first.mTime) )); - } - - if (objPos->size() != nextObjPos-1) - ++nextObjPos; - } - // A target position key is closest to us - else - { - curTime = d1; - - // interpolate the other - if (1 == objPos->size() || !nextObjPos) { - curPosition = objPos->at(0).mValue; - } - else - { - const aiVectorKey& last = objPos->at(nextObjPos); - const aiVectorKey& first = objPos->at(nextObjPos-1); - - curPosition = Interpolate(first.mValue, last.mValue, (ai_real) ( - (curTime-first.mTime) / (last.mTime-first.mTime))); - } - - if (targetObjPos->size() != nextTargetObjPos-1) - ++nextTargetObjPos; - } - - if (nextObjPos >= objPos->size()-1 && - nextTargetObjPos >= targetObjPos->size()-1) - { - // We reached the very last keyframe - reachedEnd = true; - } -} - -// ------------------------------------------------------------------------------------------------ -void TargetAnimationHelper::SetTargetAnimationChannel ( - const std::vector<aiVectorKey>* _targetPositions) -{ - ai_assert(NULL != _targetPositions); - targetPositions = _targetPositions; -} - -// ------------------------------------------------------------------------------------------------ -void TargetAnimationHelper::SetMainAnimationChannel ( - const std::vector<aiVectorKey>* _objectPositions) -{ - ai_assert(NULL != _objectPositions); - objectPositions = _objectPositions; -} - -// ------------------------------------------------------------------------------------------------ -void TargetAnimationHelper::SetFixedMainAnimationChannel( - const aiVector3D& fixed) -{ - objectPositions = NULL; // just to avoid confusion - fixedMain = fixed; -} - -// ------------------------------------------------------------------------------------------------ -void TargetAnimationHelper::Process(std::vector<aiVectorKey>* distanceTrack) -{ - ai_assert(NULL != targetPositions && NULL != distanceTrack); - - // TODO: in most cases we won't need the extra array - std::vector<aiVectorKey> real; - - std::vector<aiVectorKey>* fill = (distanceTrack == objectPositions ? &real : distanceTrack); - fill->reserve(std::max( objectPositions->size(), targetPositions->size() )); - - // Iterate through all object keys and interpolate their values if necessary. - // Then get the corresponding target position, compute the difference - // vector between object and target position. Then compute a rotation matrix - // that rotates the base vector of the object coordinate system at that time - // to match the diff vector. - - KeyIterator iter(objectPositions,targetPositions,&fixedMain); - for (;!iter.Finished();++iter) - { - const aiVector3D& position = iter.GetCurPosition(); - const aiVector3D& tposition = iter.GetCurTargetPosition(); - - // diff vector - aiVector3D diff = tposition - position; - ai_real f = diff.Length(); - - // output distance vector - if (f) - { - fill->push_back(aiVectorKey()); - aiVectorKey& v = fill->back(); - v.mTime = iter.GetCurTime(); - v.mValue = diff; - - diff /= f; - } - else - { - // FIXME: handle this - } - - // diff is now the vector in which our camera is pointing - } - - if (real.size()) { - *distanceTrack = real; - } -} diff --git a/thirdparty/assimp/code/Common/TargetAnimation.h b/thirdparty/assimp/code/Common/TargetAnimation.h deleted file mode 100644 index 91634ab5aa..0000000000 --- a/thirdparty/assimp/code/Common/TargetAnimation.h +++ /dev/null @@ -1,183 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a helper class for the ASE and 3DS loaders to - help them compute camera and spot light animation channels */ -#ifndef AI_TARGET_ANIMATION_H_INC -#define AI_TARGET_ANIMATION_H_INC - -#include <assimp/anim.h> -#include <vector> - -namespace Assimp { - - - -// --------------------------------------------------------------------------- -/** Helper class to iterate through all keys in an animation channel. - * - * Missing tracks are interpolated. This is a helper class for - * TargetAnimationHelper, but it can be freely used for other purposes. -*/ -class KeyIterator -{ -public: - - - // ------------------------------------------------------------------ - /** Constructs a new key iterator - * - * @param _objPos Object position track. May be NULL. - * @param _targetObjPos Target object position track. May be NULL. - * @param defaultObjectPos Default object position to be used if - * no animated track is available. May be NULL. - * @param defaultTargetPos Default target position to be used if - * no animated track is available. May be NULL. - */ - KeyIterator(const std::vector<aiVectorKey>* _objPos, - const std::vector<aiVectorKey>* _targetObjPos, - const aiVector3D* defaultObjectPos = NULL, - const aiVector3D* defaultTargetPos = NULL); - - // ------------------------------------------------------------------ - /** Returns true if all keys have been processed - */ - bool Finished() const - {return reachedEnd;} - - // ------------------------------------------------------------------ - /** Increment the iterator - */ - void operator++(); - inline void operator++(int) - {return ++(*this);} - - - - // ------------------------------------------------------------------ - /** Getters to retrieve the current state of the iterator - */ - inline const aiVector3D& GetCurPosition() const - {return curPosition;} - - inline const aiVector3D& GetCurTargetPosition() const - {return curTargetPosition;} - - inline double GetCurTime() const - {return curTime;} - -private: - - //! Did we reach the end? - bool reachedEnd; - - //! Represents the current position of the iterator - aiVector3D curPosition, curTargetPosition; - - double curTime; - - //! Input tracks and the next key to process - const std::vector<aiVectorKey>* objPos,*targetObjPos; - - unsigned int nextObjPos, nextTargetObjPos; - std::vector<aiVectorKey> defaultObjPos,defaultTargetObjPos; -}; - -// --------------------------------------------------------------------------- -/** Helper class for the 3DS and ASE loaders to compute camera and spot light - * animations. - * - * 3DS and ASE store the differently to Assimp - there is an animation - * channel for the camera/spot light itself and a separate position - * animation channels specifying the position of the camera/spot light - * look-at target */ -class TargetAnimationHelper -{ -public: - - TargetAnimationHelper() - : targetPositions (NULL) - , objectPositions (NULL) - {} - - - // ------------------------------------------------------------------ - /** Sets the target animation channel - * - * This channel specifies the position of the camera/spot light - * target at a specific position. - * - * @param targetPositions Translation channel*/ - void SetTargetAnimationChannel (const - std::vector<aiVectorKey>* targetPositions); - - - // ------------------------------------------------------------------ - /** Sets the main animation channel - * - * @param objectPositions Translation channel */ - void SetMainAnimationChannel ( const - std::vector<aiVectorKey>* objectPositions); - - // ------------------------------------------------------------------ - /** Sets the main animation channel to a fixed value - * - * @param fixed Fixed value for the main animation channel*/ - void SetFixedMainAnimationChannel(const aiVector3D& fixed); - - - // ------------------------------------------------------------------ - /** Computes final animation channels - * @param distanceTrack Receive camera translation keys ... != NULL. */ - void Process( std::vector<aiVectorKey>* distanceTrack ); - - -private: - - const std::vector<aiVectorKey>* targetPositions,*objectPositions; - aiVector3D fixedMain; -}; - - -} // ! end namespace Assimp - -#endif // include guard diff --git a/thirdparty/assimp/code/Common/Version.cpp b/thirdparty/assimp/code/Common/Version.cpp deleted file mode 100644 index cf1da7d5ba..0000000000 --- a/thirdparty/assimp/code/Common/Version.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -// Actually just a dummy, used by the compiler to build the precompiled header. - -#include <assimp/version.h> -#include <assimp/scene.h> -#include "ScenePrivate.h" - -#include "revision.h" - -// -------------------------------------------------------------------------------- -// Legal information string - don't remove this. -static const char* LEGAL_INFORMATION = - -"Open Asset Import Library (Assimp).\n" -"A free C/C++ library to import various 3D file formats into applications\n\n" - -"(c) 2006-2019, assimp team\n" -"License under the terms and conditions of the 3-clause BSD license\n" -"http://assimp.org\n" -; - -// ------------------------------------------------------------------------------------------------ -// Get legal string -ASSIMP_API const char* aiGetLegalString () { - return LEGAL_INFORMATION; -} - -// ------------------------------------------------------------------------------------------------ -// Get Assimp minor version -ASSIMP_API unsigned int aiGetVersionMinor () { - return VER_MINOR; -} - -// ------------------------------------------------------------------------------------------------ -// Get Assimp major version -ASSIMP_API unsigned int aiGetVersionMajor () { - return VER_MAJOR; -} - -// ------------------------------------------------------------------------------------------------ -// Get flags used for compilation -ASSIMP_API unsigned int aiGetCompileFlags () { - - unsigned int flags = 0; - -#ifdef ASSIMP_BUILD_BOOST_WORKAROUND - flags |= ASSIMP_CFLAGS_NOBOOST; -#endif -#ifdef ASSIMP_BUILD_SINGLETHREADED - flags |= ASSIMP_CFLAGS_SINGLETHREADED; -#endif -#ifdef ASSIMP_BUILD_DEBUG - flags |= ASSIMP_CFLAGS_DEBUG; -#endif -#ifdef ASSIMP_BUILD_DLL_EXPORT - flags |= ASSIMP_CFLAGS_SHARED; -#endif -#ifdef _STLPORT_VERSION - flags |= ASSIMP_CFLAGS_STLPORT; -#endif - - return flags; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API unsigned int aiGetVersionRevision() { - return GitVersion; -} - -ASSIMP_API const char *aiGetBranchName() { - return GitBranch; -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiScene::aiScene() -: mFlags(0) -, mRootNode(nullptr) -, mNumMeshes(0) -, mMeshes(nullptr) -, mNumMaterials(0) -, mMaterials(nullptr) -, mNumAnimations(0) -, mAnimations(nullptr) -, mNumTextures(0) -, mTextures(nullptr) -, mNumLights(0) -, mLights(nullptr) -, mNumCameras(0) -, mCameras(nullptr) -, mMetaData(nullptr) -, mPrivate(new Assimp::ScenePrivateData()) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -ASSIMP_API aiScene::~aiScene() { - // delete all sub-objects recursively - delete mRootNode; - - // To make sure we won't crash if the data is invalid it's - // much better to check whether both mNumXXX and mXXX are - // valid instead of relying on just one of them. - if (mNumMeshes && mMeshes) - for( unsigned int a = 0; a < mNumMeshes; a++) - delete mMeshes[a]; - delete [] mMeshes; - - if (mNumMaterials && mMaterials) { - for (unsigned int a = 0; a < mNumMaterials; ++a ) { - delete mMaterials[ a ]; - } - } - delete [] mMaterials; - - if (mNumAnimations && mAnimations) - for( unsigned int a = 0; a < mNumAnimations; a++) - delete mAnimations[a]; - delete [] mAnimations; - - if (mNumTextures && mTextures) - for( unsigned int a = 0; a < mNumTextures; a++) - delete mTextures[a]; - delete [] mTextures; - - if (mNumLights && mLights) - for( unsigned int a = 0; a < mNumLights; a++) - delete mLights[a]; - delete [] mLights; - - if (mNumCameras && mCameras) - for( unsigned int a = 0; a < mNumCameras; a++) - delete mCameras[a]; - delete [] mCameras; - - aiMetadata::Dealloc(mMetaData); - mMetaData = nullptr; - - delete static_cast<Assimp::ScenePrivateData*>( mPrivate ); -} - diff --git a/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp deleted file mode 100644 index 7cfd1a3505..0000000000 --- a/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the VertexTriangleAdjacency helper class - */ - -// internal headers -#include "VertexTriangleAdjacency.h" -#include <assimp/mesh.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces, - unsigned int iNumFaces, - unsigned int iNumVertices /*= 0*/, - bool bComputeNumTriangles /*= false*/) -{ - // compute the number of referenced vertices if it wasn't specified by the caller - const aiFace* const pcFaceEnd = pcFaces + iNumFaces; - if (!iNumVertices) { - for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) { - ai_assert( nullptr != pcFace ); - ai_assert(3 == pcFace->mNumIndices); - iNumVertices = std::max(iNumVertices,pcFace->mIndices[0]); - iNumVertices = std::max(iNumVertices,pcFace->mIndices[1]); - iNumVertices = std::max(iNumVertices,pcFace->mIndices[2]); - } - } - - mNumVertices = iNumVertices; - - unsigned int* pi; - - // allocate storage - if (bComputeNumTriangles) { - pi = mLiveTriangles = new unsigned int[iNumVertices+1]; - ::memset(mLiveTriangles,0,sizeof(unsigned int)*(iNumVertices+1)); - mOffsetTable = new unsigned int[iNumVertices+2]+1; - } else { - pi = mOffsetTable = new unsigned int[iNumVertices+2]+1; - ::memset(mOffsetTable,0,sizeof(unsigned int)*(iNumVertices+1)); - mLiveTriangles = NULL; // important, otherwise the d'tor would crash - } - - // get a pointer to the end of the buffer - unsigned int* piEnd = pi+iNumVertices; - *piEnd++ = 0u; - - // first pass: compute the number of faces referencing each vertex - for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) - { - unsigned nind = pcFace->mNumIndices; - unsigned * ind = pcFace->mIndices; - if (nind > 0) pi[ind[0]]++; - if (nind > 1) pi[ind[1]]++; - if (nind > 2) pi[ind[2]]++; - } - - // second pass: compute the final offset table - unsigned int iSum = 0; - unsigned int* piCurOut = this->mOffsetTable; - for (unsigned int* piCur = pi; piCur != piEnd;++piCur,++piCurOut) { - - unsigned int iLastSum = iSum; - iSum += *piCur; - *piCurOut = iLastSum; - } - pi = this->mOffsetTable; - - // third pass: compute the final table - this->mAdjacencyTable = new unsigned int[iSum]; - iSum = 0; - for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace,++iSum) { - unsigned nind = pcFace->mNumIndices; - unsigned * ind = pcFace->mIndices; - - if (nind > 0) mAdjacencyTable[pi[ind[0]]++] = iSum; - if (nind > 1) mAdjacencyTable[pi[ind[1]]++] = iSum; - if (nind > 2) mAdjacencyTable[pi[ind[2]]++] = iSum; - } - // fourth pass: undo the offset computations made during the third pass - // We could do this in a separate buffer, but this would be TIMES slower. - --mOffsetTable; - *mOffsetTable = 0u; -} -// ------------------------------------------------------------------------------------------------ -VertexTriangleAdjacency::~VertexTriangleAdjacency() -{ - // delete allocated storage - delete[] mOffsetTable; - delete[] mAdjacencyTable; - delete[] mLiveTriangles; -} diff --git a/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h deleted file mode 100644 index f3be47612d..0000000000 --- a/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a helper class to compute a vertex-triangle adjacency map */ -#ifndef AI_VTADJACENCY_H_INC -#define AI_VTADJACENCY_H_INC - -#include "BaseProcess.h" -#include <assimp/types.h> -#include <assimp/ai_assert.h> - -struct aiMesh; -struct aiFace; - -namespace Assimp { - -// -------------------------------------------------------------------------------------------- -/** @brief The VertexTriangleAdjacency class computes a vertex-triangle - * adjacency map from a given index buffer. - * - * @note Although it is called #VertexTriangleAdjacency, the current version does also - * support arbitrary polygons. */ -// -------------------------------------------------------------------------------------------- -class ASSIMP_API VertexTriangleAdjacency { -public: - // ---------------------------------------------------------------------------- - /** @brief Construction from an existing index buffer - * @param pcFaces Index buffer - * @param iNumFaces Number of faces in the buffer - * @param iNumVertices Number of referenced vertices. This value - * is computed automatically if 0 is specified. - * @param bComputeNumTriangles If you want the class to compute - * a list containing the number of referenced triangles per vertex - * per vertex - pass true. */ - VertexTriangleAdjacency(aiFace* pcFaces,unsigned int iNumFaces, - unsigned int iNumVertices = 0, - bool bComputeNumTriangles = true); - - // ---------------------------------------------------------------------------- - /** @brief Destructor */ - ~VertexTriangleAdjacency(); - - // ---------------------------------------------------------------------------- - /** @brief Get all triangles adjacent to a vertex - * @param iVertIndex Index of the vertex - * @return A pointer to the adjacency list. */ - unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const { - ai_assert(iVertIndex < mNumVertices); - return &mAdjacencyTable[ mOffsetTable[iVertIndex]]; - } - - // ---------------------------------------------------------------------------- - /** @brief Get the number of triangles that are referenced by - * a vertex. This function returns a reference that can be modified - * @param iVertIndex Index of the vertex - * @return Number of referenced triangles */ - unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex) { - ai_assert( iVertIndex < mNumVertices ); - ai_assert( nullptr != mLiveTriangles ); - return mLiveTriangles[iVertIndex]; - } - - //! Offset table - unsigned int* mOffsetTable; - - //! Adjacency table - unsigned int* mAdjacencyTable; - - //! Table containing the number of referenced triangles per vertex - unsigned int* mLiveTriangles; - - //! Debug: Number of referenced vertices - unsigned int mNumVertices; -}; - -} //! ns Assimp - -#endif // !! AI_VTADJACENCY_H_INC diff --git a/thirdparty/assimp/code/Common/Win32DebugLogStream.h b/thirdparty/assimp/code/Common/Win32DebugLogStream.h deleted file mode 100644 index a6063a261e..0000000000 --- a/thirdparty/assimp/code/Common/Win32DebugLogStream.h +++ /dev/null @@ -1,95 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Win32DebugLogStream.h -* @brief Implementation of Win32DebugLogStream -*/ -#ifndef AI_WIN32DEBUGLOGSTREAM_H_INC -#define AI_WIN32DEBUGLOGSTREAM_H_INC - -#ifdef _WIN32 - -#include <assimp/LogStream.hpp> -#include "windows.h" - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** @class Win32DebugLogStream - * @brief Logs into the debug stream from win32. - */ -class Win32DebugLogStream : public LogStream { -public: - /** @brief Default constructor */ - Win32DebugLogStream(); - - /** @brief Destructor */ - ~Win32DebugLogStream(); - - /** @brief Writer */ - void write(const char* messgae); -}; - -// --------------------------------------------------------------------------- -inline -Win32DebugLogStream::Win32DebugLogStream(){ - // empty -} - -// --------------------------------------------------------------------------- -inline -Win32DebugLogStream::~Win32DebugLogStream(){ - // empty -} - -// --------------------------------------------------------------------------- -inline -void Win32DebugLogStream::write(const char* message) { - ::OutputDebugStringA( message); -} - -// --------------------------------------------------------------------------- -} // Namespace Assimp - -#endif // ! _WIN32 -#endif // guard diff --git a/thirdparty/assimp/code/Common/assbin_chunks.h b/thirdparty/assimp/code/Common/assbin_chunks.h deleted file mode 100644 index 15e4af5e7d..0000000000 --- a/thirdparty/assimp/code/Common/assbin_chunks.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef INCLUDED_ASSBIN_CHUNKS_H -#define INCLUDED_ASSBIN_CHUNKS_H - -#define ASSBIN_VERSION_MAJOR 1 -#define ASSBIN_VERSION_MINOR 0 - -/** -@page assfile .ASS File formats - -@section over Overview -Assimp provides its own interchange format, which is intended to applications which need -to serialize 3D-models and to reload them quickly. Assimp's file formats are designed to -be read by Assimp itself. They encode additional information needed by Assimp to optimize -its postprocessing pipeline. If you once apply specific steps to a scene, then save it -and reread it from an ASS format using the same post processing settings, they won't -be executed again. - -The format comes in two flavours: XML and binary - both of them hold a complete dump of -the 'aiScene' data structure returned by the APIs. The focus for the binary format -(<tt>.assbin</tt>) is fast loading. Optional deflate compression helps reduce file size. The XML -flavour, <tt>.assxml</tt> or simply .xml, is just a plain-to-xml conversion of aiScene. - -ASSBIN is Assimp's binary interchange format. assimp_cmd (<tt><root>/tools/assimp_cmd</tt>) is able to -write it and the core library provides a loader for it. - -@section assxml XML File format - -The format is pretty much self-explanatory due to its similarity to the in-memory aiScene structure. -With few exceptions, C structures are wrapped in XML elements. - -The DTD for ASSXML can be found in <tt><root>/doc/AssXML_Scheme.xml</tt>. Or have look -at the output files generated by assimp_cmd. - -@section assbin Binary file format - -The ASSBIN file format is composed of chunks to represent the hierarchical aiScene data structure. -This makes the format extensible and allows backward-compatibility with future data structure -versions. The <tt><root>/code/assbin_chunks.h</tt> header contains some magic constants -for use by stand-alone ASSBIN loaders. Also, Assimp's own file writer can be found -in <tt><root>/tools/assimp_cmd/WriteDumb.cpp</tt> (yes, the 'b' is no typo ...). - -@verbatim - -------------------------------------------------------------------------------- -1. File structure: -------------------------------------------------------------------------------- - ----------------------- -| Header (512 bytes) | ----------------------- -| Variable chunks | ----------------------- - -------------------------------------------------------------------------------- -2. Definitions: -------------------------------------------------------------------------------- - -integer is four bytes wide, stored in little-endian byte order. -short is two bytes wide, stored in little-endian byte order. -byte is a single byte. -string is an integer n followed by n UTF-8 characters, not terminated by zero -float is an IEEE 754 single-precision floating-point value -double is an IEEE 754 double-precision floating-point value -t[n] is an array of n elements of type t - -------------------------------------------------------------------------------- -2. Header: -------------------------------------------------------------------------------- - -byte[44] Magic identification string for ASSBIN files. - 'ASSIMP.binary' - -integer Major version of the Assimp library which wrote the file -integer Minor version of the Assimp library which wrote the file - match these against ASSBIN_VERSION_MAJOR and ASSBIN_VERSION_MINOR - -integer SVN revision of the Assimp library (intended for our internal - debugging - if you write Ass files from your own APPs, set this value to 0. -integer Assimp compile flags - -short 0 for normal files, 1 for shortened dumps for regression tests - these should have the file extension assbin.regress - -short 1 if the data after the header is compressed with the DEFLATE algorithm, - 0 for uncompressed files. - For compressed files, the first integer after the header is - always the uncompressed data size - -byte[256] Zero-terminated source file name, UTF-8 -byte[128] Zero-terminated command line parameters passed to assimp_cmd, UTF-8 - -byte[64] Reserved for future use ----> Total length: 512 bytes - -------------------------------------------------------------------------------- -3. Chunks: -------------------------------------------------------------------------------- - -integer Magic chunk ID (ASSBIN_CHUNK_XXX) -integer Chunk data length, in bytes - (unknown chunks are possible, a good reader skips over them) - (chunk-data-length does not include the first two integers) - -byte[n] chunk-data-length bytes of data, depending on the chunk type - -Chunks can contain nested chunks. Nested chunks are ALWAYS at the end of the chunk, -their size is included in chunk-data-length. - -The chunk layout for all ASSIMP data structures is derived from their C declarations. -The general 'rule' to get from Assimp headers to the serialized layout is: - - 1. POD members (i.e. aiMesh::mPrimitiveTypes, aiMesh::mNumVertices), - in order of declaration. - - 2. Array-members (aiMesh::mFaces, aiMesh::mVertices, aiBone::mWeights), - in order of declaration. - - 2. Object array members (i.e aiMesh::mBones, aiScene::mMeshes) are stored in - subchunks directly following the data written in 1.) and 2.) - - - Of course, there are some exceptions to this general order: - -[[aiScene]] - - - The root node holding the scene structure is naturally stored in - a ASSBIN_CHUNK_AINODE subchunk following 1.) and 2.) (which is - empty for aiScene). - -[[aiMesh]] - - - mTextureCoords and mNumUVComponents are serialized as follows: - - [number of used uv channels times] - integer mNumUVComponents[n] - float mTextureCoords[n][3] - - -> more than AI_MAX_TEXCOORD_CHANNELS can be stored. This allows Assimp - builds with different settings for AI_MAX_TEXCOORD_CHANNELS to exchange - data. - -> the on-disk format always uses 3 floats to write UV coordinates. - If mNumUVComponents[0] is 1, the corresponding mTextureCoords array - consists of 3 floats. - - - The array member block of aiMesh is prefixed with an integer that specifies - the kinds of vertex components actually present in the mesh. This is a - bitwise combination of the ASSBIN_MESH_HAS_xxx constants. - -[[aiFace]] - - - mNumIndices is stored as short - - mIndices are written as short, if aiMesh::mNumVertices<65536 - -[[aiNode]] - - - mParent is omitted - -[[aiLight]] - - - mAttenuationXXX not written if aiLight::mType == aiLightSource_DIRECTIONAL - - mAngleXXX not written if aiLight::mType != aiLightSource_SPOT - -[[aiMaterial]] - - - mNumAllocated is omitted, for obvious reasons :-) - - - @endverbatim*/ - - -#define ASSBIN_HEADER_LENGTH 512 - -// these are the magic chunk identifiers for the binary ASS file format -#define ASSBIN_CHUNK_AICAMERA 0x1234 -#define ASSBIN_CHUNK_AILIGHT 0x1235 -#define ASSBIN_CHUNK_AITEXTURE 0x1236 -#define ASSBIN_CHUNK_AIMESH 0x1237 -#define ASSBIN_CHUNK_AINODEANIM 0x1238 -#define ASSBIN_CHUNK_AISCENE 0x1239 -#define ASSBIN_CHUNK_AIBONE 0x123a -#define ASSBIN_CHUNK_AIANIMATION 0x123b -#define ASSBIN_CHUNK_AINODE 0x123c -#define ASSBIN_CHUNK_AIMATERIAL 0x123d -#define ASSBIN_CHUNK_AIMATERIALPROPERTY 0x123e - -#define ASSBIN_MESH_HAS_POSITIONS 0x1 -#define ASSBIN_MESH_HAS_NORMALS 0x2 -#define ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS 0x4 -#define ASSBIN_MESH_HAS_TEXCOORD_BASE 0x100 -#define ASSBIN_MESH_HAS_COLOR_BASE 0x10000 - -#define ASSBIN_MESH_HAS_TEXCOORD(n) (ASSBIN_MESH_HAS_TEXCOORD_BASE << n) -#define ASSBIN_MESH_HAS_COLOR(n) (ASSBIN_MESH_HAS_COLOR_BASE << n) - - -#endif // INCLUDED_ASSBIN_CHUNKS_H diff --git a/thirdparty/assimp/code/Common/scene.cpp b/thirdparty/assimp/code/Common/scene.cpp deleted file mode 100644 index d15619acff..0000000000 --- a/thirdparty/assimp/code/Common/scene.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -#include <assimp/scene.h> - -aiNode::aiNode() -: mName("") -, mParent(nullptr) -, mNumChildren(0) -, mChildren(nullptr) -, mNumMeshes(0) -, mMeshes(nullptr) -, mMetaData(nullptr) { - // empty -} - -aiNode::aiNode(const std::string& name) -: mName(name) -, mParent(nullptr) -, mNumChildren(0) -, mChildren(nullptr) -, mNumMeshes(0) -, mMeshes(nullptr) -, mMetaData(nullptr) { - // empty -} - -/** Destructor */ -aiNode::~aiNode() { - // delete all children recursively - // to make sure we won't crash if the data is invalid ... - if (mNumChildren && mChildren) - { - for (unsigned int a = 0; a < mNumChildren; a++) - delete mChildren[a]; - } - delete[] mChildren; - delete[] mMeshes; - delete mMetaData; -} - -const aiNode *aiNode::FindNode(const char* name) const { - if (nullptr == name) { - return nullptr; - } - if (!::strcmp(mName.data, name)) { - return this; - } - for (unsigned int i = 0; i < mNumChildren; ++i) { - const aiNode* const p = mChildren[i]->FindNode(name); - if (p) { - return p; - } - } - // there is definitely no sub-node with this name - return nullptr; -} - -aiNode *aiNode::FindNode(const char* name) { - if (!::strcmp(mName.data, name))return this; - for (unsigned int i = 0; i < mNumChildren; ++i) - { - aiNode* const p = mChildren[i]->FindNode(name); - if (p) { - return p; - } - } - // there is definitely no sub-node with this name - return nullptr; -} - -void aiNode::addChildren(unsigned int numChildren, aiNode **children) { - if (nullptr == children || 0 == numChildren) { - return; - } - - for (unsigned int i = 0; i < numChildren; i++) { - aiNode *child = children[i]; - if (nullptr != child) { - child->mParent = this; - } - } - - if (mNumChildren > 0) { - aiNode **tmp = new aiNode*[mNumChildren]; - ::memcpy(tmp, mChildren, sizeof(aiNode*) * mNumChildren); - delete[] mChildren; - mChildren = new aiNode*[mNumChildren + numChildren]; - ::memcpy(mChildren, tmp, sizeof(aiNode*) * mNumChildren); - ::memcpy(&mChildren[mNumChildren], children, sizeof(aiNode*)* numChildren); - mNumChildren += numChildren; - delete[] tmp; - } - else { - mChildren = new aiNode*[numChildren]; - for (unsigned int i = 0; i < numChildren; i++) { - mChildren[i] = children[i]; - } - mNumChildren = numChildren; - } -} diff --git a/thirdparty/assimp/code/Common/simd.cpp b/thirdparty/assimp/code/Common/simd.cpp deleted file mode 100644 index 04615f408e..0000000000 --- a/thirdparty/assimp/code/Common/simd.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -#include "simd.h" - -namespace Assimp { - -bool CPUSupportsSSE2() { -#if defined(__x86_64__) || defined(_M_X64) - //* x86_64 always has SSE2 instructions */ - return true; -#elif defined(__GNUC__) && defined(i386) - // for GCC x86 we check cpuid - unsigned int d; - __asm__( - "pushl %%ebx\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - : "=d" ( d ) - :"a" ( 1 ) ); - return ( d & 0x04000000 ) != 0; -#elif (defined(_MSC_VER) && defined(_M_IX86)) - // also check cpuid for MSVC x86 - unsigned int d; - __asm { - xor eax, eax - inc eax - push ebx - cpuid - pop ebx - mov d, edx - } - return ( d & 0x04000000 ) != 0; -#else - return false; -#endif -} - - -} // Namespace Assimp diff --git a/thirdparty/assimp/code/Common/simd.h b/thirdparty/assimp/code/Common/simd.h deleted file mode 100644 index 3eecdd4581..0000000000 --- a/thirdparty/assimp/code/Common/simd.h +++ /dev/null @@ -1,53 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -#pragma once - -#include <assimp/defs.h> - -namespace Assimp { - -/// @brief Checks if the platform supports SSE2 optimization -/// @return true, if SSE2 is supported. false if SSE2 is not supported. -bool ASSIMP_API CPUSupportsSSE2(); - -} // Namespace Assimp diff --git a/thirdparty/assimp/code/FBX/FBXAnimation.cpp b/thirdparty/assimp/code/FBX/FBXAnimation.cpp deleted file mode 100644 index 874914431b..0000000000 --- a/thirdparty/assimp/code/FBX/FBXAnimation.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXAnimation.cpp - * @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode, - * Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXParser.h" -#include "FBXDocument.h" -#include "FBXImporter.h" -#include "FBXDocumentUtil.h" - -namespace Assimp { -namespace FBX { - -using namespace Util; - -// ------------------------------------------------------------------------------------------------ -AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/) -: Object(id, element, name) -{ - const Scope& sc = GetRequiredScope(element); - const Element& KeyTime = GetRequiredElement(sc,"KeyTime"); - const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat"); - - ParseVectorDataArray(keys, KeyTime); - ParseVectorDataArray(values, KeyValueFloat); - - if(keys.size() != values.size()) { - DOMError("the number of key times does not match the number of keyframe values",&KeyTime); - } - - // check if the key times are well-ordered - if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) { - DOMError("the keyframes are not in ascending order",&KeyTime); - } - - const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"]; - if(KeyAttrDataFloat) { - ParseVectorDataArray(attributes, *KeyAttrDataFloat); - } - - const Element* KeyAttrFlags = sc["KeyAttrFlags"]; - if(KeyAttrFlags) { - ParseVectorDataArray(flags, *KeyAttrFlags); - } -} - -// ------------------------------------------------------------------------------------------------ -AnimationCurve::~AnimationCurve() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, - const Document& doc, const char* const * target_prop_whitelist /*= NULL*/, - size_t whitelist_size /*= 0*/) -: Object(id, element, name) -, target() -, doc(doc) -{ - const Scope& sc = GetRequiredScope(element); - - // find target node - const char* whitelist[] = {"Model","NodeAttribute","Deformer"}; - const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,3); - - for(const Connection* con : conns) { - - // link should go for a property - if (!con->PropertyName().length()) { - continue; - } - - if(target_prop_whitelist) { - const char* const s = con->PropertyName().c_str(); - bool ok = false; - for (size_t i = 0; i < whitelist_size; ++i) { - if (!strcmp(s, target_prop_whitelist[i])) { - ok = true; - break; - } - } - - if (!ok) { - throw std::range_error("AnimationCurveNode target property is not in whitelist"); - } - } - - const Object* const ob = con->DestinationObject(); - if(!ob) { - DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element); - continue; - } - - // XXX support constraints as DOM class - //ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob)); - target = ob; - if(!target) { - continue; - } - - prop = con->PropertyName(); - break; - } - - if(!target) { - DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element); - } - - props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false); -} - -// ------------------------------------------------------------------------------------------------ -AnimationCurveNode::~AnimationCurveNode() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -const AnimationCurveMap& AnimationCurveNode::Curves() const -{ - if ( curves.empty() ) { - // resolve attached animation curves - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve"); - - for(const Connection* con : conns) { - - // link should go for a property - if (!con->PropertyName().length()) { - continue; - } - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element); - continue; - } - - const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob); - if(!anim) { - DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element); - continue; - } - - curves[con->PropertyName()] = anim; - } - } - - return curves; -} - -// ------------------------------------------------------------------------------------------------ -AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Object(id, element, name) -, doc(doc) -{ - const Scope& sc = GetRequiredScope(element); - - // note: the props table here bears little importance and is usually absent - props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true); -} - -// ------------------------------------------------------------------------------------------------ -AnimationLayer::~AnimationLayer() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, - size_t whitelist_size /*= 0*/) const -{ - AnimationCurveNodeList nodes; - - // resolve attached animation nodes - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode"); - nodes.reserve(conns.size()); - - for(const Connection* con : conns) { - - // link should not go to a property - if (con->PropertyName().length()) { - continue; - } - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element); - continue; - } - - const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob); - if(!anim) { - DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element); - continue; - } - - if(target_prop_whitelist) { - const char* s = anim->TargetProperty().c_str(); - bool ok = false; - for (size_t i = 0; i < whitelist_size; ++i) { - if (!strcmp(s, target_prop_whitelist[i])) { - ok = true; - break; - } - } - if(!ok) { - continue; - } - } - nodes.push_back(anim); - } - - return nodes; // pray for NRVO -} - -// ------------------------------------------------------------------------------------------------ -AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Object(id, element, name) -{ - const Scope& sc = GetRequiredScope(element); - - // note: we don't currently use any of these properties so we shouldn't bother if it is missing - props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true); - - // resolve attached animation layers - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer"); - layers.reserve(conns.size()); - - for(const Connection* con : conns) { - - // link should not go to a property - if (con->PropertyName().length()) { - continue; - } - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element); - continue; - } - - const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob); - if(!anim) { - DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element); - continue; - } - layers.push_back(anim); - } -} - -// ------------------------------------------------------------------------------------------------ -AnimationStack::~AnimationStack() -{ - // empty -} - -} //!FBX -} //!Assimp - -#endif // ASSIMP_BUILD_NO_FBX_IMPORTER diff --git a/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp b/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp deleted file mode 100644 index a4a2bc8e79..0000000000 --- a/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -/** @file FBXBinaryTokenizer.cpp - * @brief Implementation of a fake lexer for binary fbx files - - * we emit tokens so the parser needs almost no special handling - * for binary files. - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXTokenizer.h" -#include "FBXUtil.h" -#include <assimp/defs.h> -#include <stdint.h> -#include <assimp/Exceptional.h> -#include <assimp/ByteSwapper.h> - -namespace Assimp { -namespace FBX { - -//enum Flag -//{ -// e_unknown_0 = 1 << 0, -// e_unknown_1 = 1 << 1, -// e_unknown_2 = 1 << 2, -// e_unknown_3 = 1 << 3, -// e_unknown_4 = 1 << 4, -// e_unknown_5 = 1 << 5, -// e_unknown_6 = 1 << 6, -// e_unknown_7 = 1 << 7, -// e_unknown_8 = 1 << 8, -// e_unknown_9 = 1 << 9, -// e_unknown_10 = 1 << 10, -// e_unknown_11 = 1 << 11, -// e_unknown_12 = 1 << 12, -// e_unknown_13 = 1 << 13, -// e_unknown_14 = 1 << 14, -// e_unknown_15 = 1 << 15, -// e_unknown_16 = 1 << 16, -// e_unknown_17 = 1 << 17, -// e_unknown_18 = 1 << 18, -// e_unknown_19 = 1 << 19, -// e_unknown_20 = 1 << 20, -// e_unknown_21 = 1 << 21, -// e_unknown_22 = 1 << 22, -// e_unknown_23 = 1 << 23, -// e_flag_field_size_64_bit = 1 << 24, // Not sure what is -// e_unknown_25 = 1 << 25, -// e_unknown_26 = 1 << 26, -// e_unknown_27 = 1 << 27, -// e_unknown_28 = 1 << 28, -// e_unknown_29 = 1 << 29, -// e_unknown_30 = 1 << 30, -// e_unknown_31 = 1 << 31 -//}; -// -//bool check_flag(uint32_t flags, Flag to_check) -//{ -// return (flags & to_check) != 0; -//} -// ------------------------------------------------------------------------------------------------ -Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset) - : - #ifdef DEBUG - contents(sbegin, static_cast<size_t>(send-sbegin)), - #endif - sbegin(sbegin) - , send(send) - , type(type) - , line(offset) - , column(BINARY_MARKER) -{ - ai_assert(sbegin); - ai_assert(send); - - // binary tokens may have zero length because they are sometimes dummies - // inserted by TokenizeBinary() - ai_assert(send >= sbegin); -} - - -namespace { - -// ------------------------------------------------------------------------------------------------ -// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError. -AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset) AI_WONT_RETURN_SUFFIX; -AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset) -{ - throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset)); -} - - -// ------------------------------------------------------------------------------------------------ -size_t Offset(const char* begin, const char* cursor) { - ai_assert(begin <= cursor); - - return cursor - begin; -} - -// ------------------------------------------------------------------------------------------------ -void TokenizeError(const std::string& message, const char* begin, const char* cursor) { - TokenizeError(message, Offset(begin, cursor)); -} - -// ------------------------------------------------------------------------------------------------ -uint32_t ReadWord(const char* input, const char*& cursor, const char* end) { - const size_t k_to_read = sizeof( uint32_t ); - if(Offset(cursor, end) < k_to_read ) { - TokenizeError("cannot ReadWord, out of bounds",input, cursor); - } - - uint32_t word; - ::memcpy(&word, cursor, 4); - AI_SWAP4(word); - - cursor += k_to_read; - - return word; -} - -// ------------------------------------------------------------------------------------------------ -uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end) { - const size_t k_to_read = sizeof(uint64_t); - if(Offset(cursor, end) < k_to_read) { - TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor); - } - - uint64_t dword /*= *reinterpret_cast<const uint64_t*>(cursor)*/; - ::memcpy( &dword, cursor, sizeof( uint64_t ) ); - AI_SWAP8(dword); - - cursor += k_to_read; - - return dword; -} - -// ------------------------------------------------------------------------------------------------ -uint8_t ReadByte(const char* input, const char*& cursor, const char* end) { - if(Offset(cursor, end) < sizeof( uint8_t ) ) { - TokenizeError("cannot ReadByte, out of bounds",input, cursor); - } - - uint8_t word;/* = *reinterpret_cast< const uint8_t* >( cursor )*/ - ::memcpy( &word, cursor, sizeof( uint8_t ) ); - ++cursor; - - return word; -} - -// ------------------------------------------------------------------------------------------------ -unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, - const char*& cursor, const char* end, bool long_length = false, bool allow_null = false) { - const uint32_t len_len = long_length ? 4 : 1; - if(Offset(cursor, end) < len_len) { - TokenizeError("cannot ReadString, out of bounds reading length",input, cursor); - } - - const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end); - - if (Offset(cursor, end) < length) { - TokenizeError("cannot ReadString, length is out of bounds",input, cursor); - } - - sbegin_out = cursor; - cursor += length; - - send_out = cursor; - - if(!allow_null) { - for (unsigned int i = 0; i < length; ++i) { - if(sbegin_out[i] == '\0') { - TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor); - } - } - } - - return length; -} - -// ------------------------------------------------------------------------------------------------ -void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) { - if(Offset(cursor, end) < 1) { - TokenizeError("cannot ReadData, out of bounds reading length",input, cursor); - } - - const char type = *cursor; - sbegin_out = cursor++; - - switch(type) - { - // 16 bit int - case 'Y': - cursor += 2; - break; - - // 1 bit bool flag (yes/no) - case 'C': - cursor += 1; - break; - - // 32 bit int - case 'I': - // <- fall through - - // float - case 'F': - cursor += 4; - break; - - // double - case 'D': - cursor += 8; - break; - - // 64 bit int - case 'L': - cursor += 8; - break; - - // note: do not write cursor += ReadWord(...cursor) as this would be UB - - // raw binary data - case 'R': - { - const uint32_t length = ReadWord(input, cursor, end); - cursor += length; - break; - } - - case 'b': - // TODO: what is the 'b' type code? Right now we just skip over it / - // take the full range we could get - cursor = end; - break; - - // array of * - case 'f': - case 'd': - case 'l': - case 'i': - case 'c': { - const uint32_t length = ReadWord(input, cursor, end); - const uint32_t encoding = ReadWord(input, cursor, end); - - const uint32_t comp_len = ReadWord(input, cursor, end); - - // compute length based on type and check against the stored value - if(encoding == 0) { - uint32_t stride = 0; - switch(type) - { - case 'f': - case 'i': - stride = 4; - break; - - case 'd': - case 'l': - stride = 8; - break; - - case 'c': - stride = 1; - break; - - default: - ai_assert(false); - }; - ai_assert(stride > 0); - if(length * stride != comp_len) { - TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor); - } - } - // zip/deflate algorithm (encoding==1)? take given length. anything else? die - else if (encoding != 1) { - TokenizeError("cannot ReadData, unknown encoding",input, cursor); - } - cursor += comp_len; - break; - } - - // string - case 'S': { - const char* sb, *se; - // 0 characters can legally happen in such strings - ReadString(sb, se, input, cursor, end, true, true); - break; - } - default: - TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor); - } - - if(cursor > end) { - TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor); - } - - // the type code is contained in the returned range - send_out = cursor; -} - - -// ------------------------------------------------------------------------------------------------ -bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, bool const is64bits) -{ - // the first word contains the offset at which this block ends - const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); - - // we may get 0 if reading reached the end of the file - - // fbx files have a mysterious extra footer which I don't know - // how to extract any information from, but at least it always - // starts with a 0. - if(!end_offset) { - return false; - } - - if(end_offset > Offset(input, end)) { - TokenizeError("block offset is out of range",input, cursor); - } - else if(end_offset < Offset(input, cursor)) { - TokenizeError("block offset is negative out of range",input, cursor); - } - - // the second data word contains the number of properties in the scope - const uint64_t prop_count = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); - - // the third data word contains the length of the property list - const uint64_t prop_length = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); - - // now comes the name of the scope/key - const char* sbeg, *send; - ReadString(sbeg, send, input, cursor, end); - - output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) )); - - // now come the individual properties - const char* begin_cursor = cursor; - for (unsigned int i = 0; i < prop_count; ++i) { - ReadData(sbeg, send, input, cursor, begin_cursor + prop_length); - - output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) )); - - if(i != prop_count-1) { - output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) )); - } - } - - if (Offset(begin_cursor, cursor) != prop_length) { - TokenizeError("property length not reached, something is wrong",input, cursor); - } - - // at the end of each nested block, there is a NUL record to indicate - // that the sub-scope exists (i.e. to distinguish between P: and P : {}) - // this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit. - const size_t sentinel_block_length = is64bits ? (sizeof(uint64_t)* 3 + 1) : (sizeof(uint32_t)* 3 + 1); - - if (Offset(input, cursor) < end_offset) { - if (end_offset - Offset(input, cursor) < sentinel_block_length) { - TokenizeError("insufficient padding bytes at block end",input, cursor); - } - - output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) )); - - // XXX this is vulnerable to stack overflowing .. - while(Offset(input, cursor) < end_offset - sentinel_block_length) { - ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits); - } - output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) )); - - for (unsigned int i = 0; i < sentinel_block_length; ++i) { - if(cursor[i] != '\0') { - TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor); - } - } - cursor += sentinel_block_length; - } - - if (Offset(input, cursor) != end_offset) { - TokenizeError("scope length not reached, something is wrong",input, cursor); - } - - return true; -} - -} // anonymous namespace - -// ------------------------------------------------------------------------------------------------ -// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent -void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length) -{ - ai_assert(input); - - if(length < 0x1b) { - TokenizeError("file is too short",0); - } - - //uint32_t offset = 0x15; -/* const char* cursor = input + 0x15; - - const uint32_t flags = ReadWord(input, cursor, input + length); - - const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused - const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused*/ - - if (strncmp(input,"Kaydara FBX Binary",18)) { - TokenizeError("magic bytes not found",0); - } - - const char* cursor = input + 18; - /*Result ignored*/ ReadByte(input, cursor, input + length); - /*Result ignored*/ ReadByte(input, cursor, input + length); - /*Result ignored*/ ReadByte(input, cursor, input + length); - /*Result ignored*/ ReadByte(input, cursor, input + length); - /*Result ignored*/ ReadByte(input, cursor, input + length); - const uint32_t version = ReadWord(input, cursor, input + length); - const bool is64bits = version >= 7500; - const char *end = input + length; - while (cursor < end ) { - if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) { - break; - } - } -} - -} // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXCommon.h b/thirdparty/assimp/code/FBX/FBXCommon.h deleted file mode 100644 index e516449130..0000000000 --- a/thirdparty/assimp/code/FBX/FBXCommon.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXCommon.h -* Some useful constants and enums for dealing with FBX files. -*/ -#ifndef AI_FBXCOMMON_H_INC -#define AI_FBXCOMMON_H_INC - -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -namespace Assimp { -namespace FBX -{ - const std::string NULL_RECORD = { // 13 null bytes - '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0' - }; // who knows why - const std::string SEPARATOR = {'\x00', '\x01'}; // for use inside strings - const std::string MAGIC_NODE_TAG = "_$AssimpFbx$"; // from import - const int64_t SECOND = 46186158000; // FBX's kTime unit - - // rotation order. We'll probably use EulerXYZ for everything - enum RotOrder { - RotOrder_EulerXYZ = 0, - RotOrder_EulerXZY, - RotOrder_EulerYZX, - RotOrder_EulerYXZ, - RotOrder_EulerZXY, - RotOrder_EulerZYX, - - RotOrder_SphericXYZ, - - RotOrder_MAX // end-of-enum sentinel - }; - - // transformation inheritance method. Most of the time RSrs - enum TransformInheritance { - TransformInheritance_RrSs = 0, - TransformInheritance_RSrs, - TransformInheritance_Rrs, - - TransformInheritance_MAX // end-of-enum sentinel - }; -} -} -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER - -#endif // AI_FBXCOMMON_H_INC diff --git a/thirdparty/assimp/code/FBX/FBXCompileConfig.h b/thirdparty/assimp/code/FBX/FBXCompileConfig.h deleted file mode 100644 index 03536a1823..0000000000 --- a/thirdparty/assimp/code/FBX/FBXCompileConfig.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXCompileConfig.h - * @brief FBX importer compile-time switches - */ -#ifndef INCLUDED_AI_FBX_COMPILECONFIG_H -#define INCLUDED_AI_FBX_COMPILECONFIG_H - -#include <map> -#include <set> - -// -#if _MSC_VER > 1500 || (defined __GNUC___) -# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP -# else -# define fbx_unordered_map map -# define fbx_unordered_multimap multimap -# define fbx_unordered_set set -# define fbx_unordered_multiset multiset -#endif - -#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP -# include <unordered_map> -# include <unordered_set> -# if _MSC_VER > 1600 -# define fbx_unordered_map unordered_map -# define fbx_unordered_multimap unordered_multimap -# define fbx_unordered_set unordered_set -# define fbx_unordered_multiset unordered_multiset -# else -# define fbx_unordered_map tr1::unordered_map -# define fbx_unordered_multimap tr1::unordered_multimap -# define fbx_unordered_set tr1::unordered_set -# define fbx_unordered_multiset tr1::unordered_multiset -# endif -#endif - -#endif // INCLUDED_AI_FBX_COMPILECONFIG_H diff --git a/thirdparty/assimp/code/FBX/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp deleted file mode 100644 index d8a22d9f74..0000000000 --- a/thirdparty/assimp/code/FBX/FBXConverter.cpp +++ /dev/null @@ -1,3727 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXConverter.cpp - * @brief Implementation of the FBX DOM -> aiScene converter - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXConverter.h" -#include "FBXParser.h" -#include "FBXMeshGeometry.h" -#include "FBXDocument.h" -#include "FBXUtil.h" -#include "FBXProperties.h" -#include "FBXImporter.h" - -#include <assimp/StringComparison.h> -#include <assimp/MathFunctions.h> - -#include <assimp/scene.h> - -#include <assimp/CreateAnimMesh.h> - -#include <tuple> -#include <memory> -#include <iterator> -#include <vector> -#include <sstream> -#include <iomanip> -#include <cstdint> -#include <iostream> -#include <stdlib.h> - -namespace Assimp { - namespace FBX { - - using namespace Util; - -#define MAGIC_NODE_TAG "_$AssimpFbx$" - -#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL - - FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones ) - : defaultMaterialIndex() - , lights() - , cameras() - , textures() - , materials_converted() - , textures_converted() - , meshes_converted() - , node_anim_chain_bits() - , mNodeNames() - , anim_fps() - , out(out) - , doc(doc) { - // animations need to be converted first since this will - // populate the node_anim_chain_bits map, which is needed - // to determine which nodes need to be generated. - ConvertAnimations(); - // Embedded textures in FBX could be connected to nothing but to itself, - // for instance Texture -> Video connection only but not to the main graph, - // The idea here is to traverse all objects to find these Textures and convert them, - // so later during material conversion it will find converted texture in the textures_converted array. - if (doc.Settings().readTextures) - { - ConvertOrphantEmbeddedTextures(); - } - ConvertRootNode(); - - if (doc.Settings().readAllMaterials) { - // unfortunately this means we have to evaluate all objects - for (const ObjectMap::value_type& v : doc.Objects()) { - - const Object* ob = v.second->Get(); - if (!ob) { - continue; - } - - const Material* mat = dynamic_cast<const Material*>(ob); - if (mat) { - - if (materials_converted.find(mat) == materials_converted.end()) { - ConvertMaterial(*mat, 0); - } - } - } - } - - ConvertGlobalSettings(); - TransferDataToScene(); - - // if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE - // to make sure the scene passes assimp's validation. FBX files - // need not contain geometry (i.e. camera animations, raw armatures). - if (out->mNumMeshes == 0) { - out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - } - } - - - FBXConverter::~FBXConverter() { - std::for_each(meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>()); - std::for_each(materials.begin(), materials.end(), Util::delete_fun<aiMaterial>()); - std::for_each(animations.begin(), animations.end(), Util::delete_fun<aiAnimation>()); - std::for_each(lights.begin(), lights.end(), Util::delete_fun<aiLight>()); - std::for_each(cameras.begin(), cameras.end(), Util::delete_fun<aiCamera>()); - std::for_each(textures.begin(), textures.end(), Util::delete_fun<aiTexture>()); - } - - void FBXConverter::ConvertRootNode() { - out->mRootNode = new aiNode(); - std::string unique_name; - GetUniqueName("RootNode", unique_name); - out->mRootNode->mName.Set(unique_name); - - // root has ID 0 - ConvertNodes(0L, out->mRootNode, out->mRootNode); - } - - static std::string getAncestorBaseName(const aiNode* node) - { - const char* nodeName = nullptr; - size_t length = 0; - while (node && (!nodeName || length == 0)) - { - nodeName = node->mName.C_Str(); - length = node->mName.length; - node = node->mParent; - } - - if (!nodeName || length == 0) - { - return {}; - } - // could be std::string_view if c++17 available - return std::string(nodeName, length); - } - - // Make unique name - std::string FBXConverter::MakeUniqueNodeName(const Model* const model, const aiNode& parent) - { - std::string original_name = FixNodeName(model->Name()); - if (original_name.empty()) - { - original_name = getAncestorBaseName(&parent); - } - std::string unique_name; - GetUniqueName(original_name, unique_name); - return unique_name; - } - /// todo: pre-build node hierarchy - /// todo: get bone from stack - /// todo: make map of aiBone* to aiNode* - /// then update convert clusters to the new format - void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) { - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model"); - - std::vector<aiNode*> nodes; - nodes.reserve(conns.size()); - - std::vector<aiNode*> nodes_chain; - std::vector<aiNode*> post_nodes_chain; - - try { - for (const Connection* con : conns) { - // ignore object-property links - if (con->PropertyName().length()) { - // really important we document why this is ignored. - FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored"); - continue; //? - } - - // convert connection source object into Object base class - const Object* const object = con->SourceObject(); - if (nullptr == object) { - FBXImporter::LogError("failed to convert source object for Model link"); - continue; - } - - // FBX Model::Cube, Model::Bone001, etc elements - // This detects if we can cast the object into this model structure. - const Model* const model = dynamic_cast<const Model*>(object); - - if (nullptr != model) { - nodes_chain.clear(); - post_nodes_chain.clear(); - - aiMatrix4x4 new_abs_transform = parent->mTransformation; - std::string node_name = FixNodeName(model->Name()); - // even though there is only a single input node, the design of - // assimp (or rather: the complicated transformation chain that - // is employed by fbx) means that we may need multiple aiNode's - // to represent a fbx node's transformation. - - - // generate node transforms - this includes pivot data - // if need_additional_node is true then you t - const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain); - - // assert that for the current node we must have at least a single transform - ai_assert(nodes_chain.size()); - - if (need_additional_node) { - nodes_chain.push_back(new aiNode(node_name)); - } - - //setup metadata on newest node - SetupNodeMetadata(*model, *nodes_chain.back()); - - // link all nodes in a row - aiNode* last_parent = parent; - for (aiNode* child : nodes_chain) { - ai_assert(child); - - if (last_parent != parent) { - last_parent->mNumChildren = 1; - last_parent->mChildren = new aiNode*[1]; - last_parent->mChildren[0] = child; - } - - child->mParent = last_parent; - last_parent = child; - - new_abs_transform *= child->mTransformation; - } - - // attach geometry - ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform); - - // check if there will be any child nodes - const std::vector<const Connection*>& child_conns - = doc.GetConnectionsByDestinationSequenced(model->ID(), "Model"); - - // if so, link the geometric transform inverse nodes - // before we attach any child nodes - if (child_conns.size()) { - for (aiNode* postnode : post_nodes_chain) { - ai_assert(postnode); - - if (last_parent != parent) { - last_parent->mNumChildren = 1; - last_parent->mChildren = new aiNode*[1]; - last_parent->mChildren[0] = postnode; - } - - postnode->mParent = last_parent; - last_parent = postnode; - - new_abs_transform *= postnode->mTransformation; - } - } - else { - // free the nodes we allocated as we don't need them - Util::delete_fun<aiNode> deleter; - std::for_each( - post_nodes_chain.begin(), - post_nodes_chain.end(), - deleter - ); - } - - // recursion call - child nodes - ConvertNodes(model->ID(), last_parent, root_node); - - if (doc.Settings().readLights) { - ConvertLights(*model, node_name); - } - - if (doc.Settings().readCameras) { - ConvertCameras(*model, node_name); - } - - nodes.push_back(nodes_chain.front()); - nodes_chain.clear(); - } - } - - if (nodes.size()) { - parent->mChildren = new aiNode*[nodes.size()](); - parent->mNumChildren = static_cast<unsigned int>(nodes.size()); - - std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren); - } - else - { - parent->mNumChildren = 0; - parent->mChildren = nullptr; - } - - } - catch (std::exception&) { - Util::delete_fun<aiNode> deleter; - std::for_each(nodes.begin(), nodes.end(), deleter); - std::for_each(nodes_chain.begin(), nodes_chain.end(), deleter); - std::for_each(post_nodes_chain.begin(), post_nodes_chain.end(), deleter); - } - } - - - void FBXConverter::ConvertLights(const Model& model, const std::string &orig_name) { - const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); - for (const NodeAttribute* attr : node_attrs) { - const Light* const light = dynamic_cast<const Light*>(attr); - if (light) { - ConvertLight(*light, orig_name); - } - } - } - - void FBXConverter::ConvertCameras(const Model& model, const std::string &orig_name) { - const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); - for (const NodeAttribute* attr : node_attrs) { - const Camera* const cam = dynamic_cast<const Camera*>(attr); - if (cam) { - ConvertCamera(*cam, orig_name); - } - } - } - - void FBXConverter::ConvertLight(const Light& light, const std::string &orig_name) { - lights.push_back(new aiLight()); - aiLight* const out_light = lights.back(); - - out_light->mName.Set(orig_name); - - const float intensity = light.Intensity() / 100.0f; - const aiVector3D& col = light.Color(); - - out_light->mColorDiffuse = aiColor3D(col.x, col.y, col.z); - out_light->mColorDiffuse.r *= intensity; - out_light->mColorDiffuse.g *= intensity; - out_light->mColorDiffuse.b *= intensity; - - out_light->mColorSpecular = out_light->mColorDiffuse; - - //lights are defined along negative y direction - out_light->mPosition = aiVector3D(0.0f); - out_light->mDirection = aiVector3D(0.0f, -1.0f, 0.0f); - out_light->mUp = aiVector3D(0.0f, 0.0f, -1.0f); - - switch (light.LightType()) - { - case Light::Type_Point: - out_light->mType = aiLightSource_POINT; - break; - - case Light::Type_Directional: - out_light->mType = aiLightSource_DIRECTIONAL; - break; - - case Light::Type_Spot: - out_light->mType = aiLightSource_SPOT; - out_light->mAngleOuterCone = AI_DEG_TO_RAD(light.OuterAngle()); - out_light->mAngleInnerCone = AI_DEG_TO_RAD(light.InnerAngle()); - break; - - case Light::Type_Area: - FBXImporter::LogWarn("cannot represent area light, set to UNDEFINED"); - out_light->mType = aiLightSource_UNDEFINED; - break; - - case Light::Type_Volume: - FBXImporter::LogWarn("cannot represent volume light, set to UNDEFINED"); - out_light->mType = aiLightSource_UNDEFINED; - break; - default: - ai_assert(false); - } - - float decay = light.DecayStart(); - switch (light.DecayType()) - { - case Light::Decay_None: - out_light->mAttenuationConstant = decay; - out_light->mAttenuationLinear = 0.0f; - out_light->mAttenuationQuadratic = 0.0f; - break; - case Light::Decay_Linear: - out_light->mAttenuationConstant = 0.0f; - out_light->mAttenuationLinear = 2.0f / decay; - out_light->mAttenuationQuadratic = 0.0f; - break; - case Light::Decay_Quadratic: - out_light->mAttenuationConstant = 0.0f; - out_light->mAttenuationLinear = 0.0f; - out_light->mAttenuationQuadratic = 2.0f / (decay * decay); - break; - case Light::Decay_Cubic: - FBXImporter::LogWarn("cannot represent cubic attenuation, set to Quadratic"); - out_light->mAttenuationQuadratic = 1.0f; - break; - default: - ai_assert(false); - break; - } - } - - void FBXConverter::ConvertCamera(const Camera& cam, const std::string &orig_name) - { - cameras.push_back(new aiCamera()); - aiCamera* const out_camera = cameras.back(); - - out_camera->mName.Set(orig_name); - - out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight(); - - out_camera->mPosition = aiVector3D(0.0f); - out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f); - out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f); - - out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView()); - - out_camera->mClipPlaneNear = cam.NearPlane(); - out_camera->mClipPlaneFar = cam.FarPlane(); - - out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView()); - out_camera->mClipPlaneNear = cam.NearPlane(); - out_camera->mClipPlaneFar = cam.FarPlane(); - } - - void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueName) - { - uniqueName = name; - auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count - unsigned int& i = it_pair.first->second; - while (!it_pair.second) - { - i++; - std::ostringstream ext; - ext << name << std::setfill('0') << std::setw(3) << i; - uniqueName = ext.str(); - it_pair = mNodeNames.insert({ uniqueName, 0 }); - } - } - - const char* FBXConverter::NameTransformationComp(TransformationComp comp) { - switch (comp) { - case TransformationComp_Translation: - return "Translation"; - case TransformationComp_RotationOffset: - return "RotationOffset"; - case TransformationComp_RotationPivot: - return "RotationPivot"; - case TransformationComp_PreRotation: - return "PreRotation"; - case TransformationComp_Rotation: - return "Rotation"; - case TransformationComp_PostRotation: - return "PostRotation"; - case TransformationComp_RotationPivotInverse: - return "RotationPivotInverse"; - case TransformationComp_ScalingOffset: - return "ScalingOffset"; - case TransformationComp_ScalingPivot: - return "ScalingPivot"; - case TransformationComp_Scaling: - return "Scaling"; - case TransformationComp_ScalingPivotInverse: - return "ScalingPivotInverse"; - case TransformationComp_GeometricScaling: - return "GeometricScaling"; - case TransformationComp_GeometricRotation: - return "GeometricRotation"; - case TransformationComp_GeometricTranslation: - return "GeometricTranslation"; - case TransformationComp_GeometricScalingInverse: - return "GeometricScalingInverse"; - case TransformationComp_GeometricRotationInverse: - return "GeometricRotationInverse"; - case TransformationComp_GeometricTranslationInverse: - return "GeometricTranslationInverse"; - case TransformationComp_MAXIMUM: // this is to silence compiler warnings - default: - break; - } - - ai_assert(false); - - return nullptr; - } - - const char* FBXConverter::NameTransformationCompProperty(TransformationComp comp) { - switch (comp) { - case TransformationComp_Translation: - return "Lcl Translation"; - case TransformationComp_RotationOffset: - return "RotationOffset"; - case TransformationComp_RotationPivot: - return "RotationPivot"; - case TransformationComp_PreRotation: - return "PreRotation"; - case TransformationComp_Rotation: - return "Lcl Rotation"; - case TransformationComp_PostRotation: - return "PostRotation"; - case TransformationComp_RotationPivotInverse: - return "RotationPivotInverse"; - case TransformationComp_ScalingOffset: - return "ScalingOffset"; - case TransformationComp_ScalingPivot: - return "ScalingPivot"; - case TransformationComp_Scaling: - return "Lcl Scaling"; - case TransformationComp_ScalingPivotInverse: - return "ScalingPivotInverse"; - case TransformationComp_GeometricScaling: - return "GeometricScaling"; - case TransformationComp_GeometricRotation: - return "GeometricRotation"; - case TransformationComp_GeometricTranslation: - return "GeometricTranslation"; - case TransformationComp_GeometricScalingInverse: - return "GeometricScalingInverse"; - case TransformationComp_GeometricRotationInverse: - return "GeometricRotationInverse"; - case TransformationComp_GeometricTranslationInverse: - return "GeometricTranslationInverse"; - case TransformationComp_MAXIMUM: // this is to silence compiler warnings - break; - } - - ai_assert(false); - - return nullptr; - } - - aiVector3D FBXConverter::TransformationCompDefaultValue(TransformationComp comp) - { - // XXX a neat way to solve the never-ending special cases for scaling - // would be to do everything in log space! - return comp == TransformationComp_Scaling ? aiVector3D(1.f, 1.f, 1.f) : aiVector3D(); - } - - void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out) - { - if (mode == Model::RotOrder_SphericXYZ) { - FBXImporter::LogError("Unsupported RotationMode: SphericXYZ"); - out = aiMatrix4x4(); - return; - } - - const float angle_epsilon = Math::getEpsilon<float>(); - - out = aiMatrix4x4(); - - bool is_id[3] = { true, true, true }; - - aiMatrix4x4 temp[3]; - if (std::fabs(rotation.z) > angle_epsilon) { - aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z), temp[2]); - is_id[2] = false; - } - if (std::fabs(rotation.y) > angle_epsilon) { - aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y), temp[1]); - is_id[1] = false; - } - if (std::fabs(rotation.x) > angle_epsilon) { - aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x), temp[0]); - is_id[0] = false; - } - - int order[3] = { -1, -1, -1 }; - - // note: rotation order is inverted since we're left multiplying as is usual in assimp - switch (mode) - { - case Model::RotOrder_EulerXYZ: - order[0] = 2; - order[1] = 1; - order[2] = 0; - break; - - case Model::RotOrder_EulerXZY: - order[0] = 1; - order[1] = 2; - order[2] = 0; - break; - - case Model::RotOrder_EulerYZX: - order[0] = 0; - order[1] = 2; - order[2] = 1; - break; - - case Model::RotOrder_EulerYXZ: - order[0] = 2; - order[1] = 0; - order[2] = 1; - break; - - case Model::RotOrder_EulerZXY: - order[0] = 1; - order[1] = 0; - order[2] = 2; - break; - - case Model::RotOrder_EulerZYX: - order[0] = 0; - order[1] = 1; - order[2] = 2; - break; - - default: - ai_assert(false); - break; - } - - ai_assert(order[0] >= 0); - ai_assert(order[0] <= 2); - ai_assert(order[1] >= 0); - ai_assert(order[1] <= 2); - ai_assert(order[2] >= 0); - ai_assert(order[2] <= 2); - - if (!is_id[order[0]]) { - out = temp[order[0]]; - } - - if (!is_id[order[1]]) { - out = out * temp[order[1]]; - } - - if (!is_id[order[2]]) { - out = out * temp[order[2]]; - } - } - - bool FBXConverter::NeedsComplexTransformationChain(const Model& model) - { - const PropertyTable& props = model.Props(); - bool ok; - - const float zero_epsilon = 1e-6f; - const aiVector3D all_ones(1.0f, 1.0f, 1.0f); - for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) { - const TransformationComp comp = static_cast<TransformationComp>(i); - - if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation) { - continue; - } - - bool scale_compare = (comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling); - - const aiVector3D& v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok); - if (ok && scale_compare) { - if ((v - all_ones).SquareLength() > zero_epsilon) { - return true; - } - } else if (ok) { - if (v.SquareLength() > zero_epsilon) { - return true; - } - } - } - - return false; - } - - std::string FBXConverter::NameTransformationChainNode(const std::string& name, TransformationComp comp) - { - return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp); - } - - bool FBXConverter::GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes, - std::vector<aiNode*>& post_output_nodes) { - const PropertyTable& props = model.Props(); - const Model::RotOrder rot = model.RotationOrder(); - - bool ok; - - aiMatrix4x4 chain[TransformationComp_MAXIMUM]; - - ai_assert(TransformationComp_MAXIMUM < 32); - std::uint32_t chainBits = 0; - // A node won't need a node chain if it only has these. - const std::uint32_t chainMaskSimple = (1 << TransformationComp_Translation) + (1 << TransformationComp_Scaling) + (1 << TransformationComp_Rotation); - // A node will need a node chain if it has any of these. - const std::uint32_t chainMaskComplex = ((1 << (TransformationComp_MAXIMUM)) - 1) - chainMaskSimple; - - std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4()); - - // generate transformation matrices for all the different transformation components - const float zero_epsilon = Math::getEpsilon<float>(); - const aiVector3D all_ones(1.0f, 1.0f, 1.0f); - - const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok); - if (ok && PreRotation.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_PreRotation); - - GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PreRotation, chain[TransformationComp_PreRotation]); - } - - const aiVector3D& PostRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok); - if (ok && PostRotation.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_PostRotation); - - GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PostRotation, chain[TransformationComp_PostRotation]); - } - - const aiVector3D& RotationPivot = PropertyGet<aiVector3D>(props, "RotationPivot", ok); - if (ok && RotationPivot.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_RotationPivot) | (1 << TransformationComp_RotationPivotInverse); - - aiMatrix4x4::Translation(RotationPivot, chain[TransformationComp_RotationPivot]); - aiMatrix4x4::Translation(-RotationPivot, chain[TransformationComp_RotationPivotInverse]); - } - - const aiVector3D& RotationOffset = PropertyGet<aiVector3D>(props, "RotationOffset", ok); - if (ok && RotationOffset.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_RotationOffset); - - aiMatrix4x4::Translation(RotationOffset, chain[TransformationComp_RotationOffset]); - } - - const aiVector3D& ScalingOffset = PropertyGet<aiVector3D>(props, "ScalingOffset", ok); - if (ok && ScalingOffset.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_ScalingOffset); - - aiMatrix4x4::Translation(ScalingOffset, chain[TransformationComp_ScalingOffset]); - } - - const aiVector3D& ScalingPivot = PropertyGet<aiVector3D>(props, "ScalingPivot", ok); - if (ok && ScalingPivot.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_ScalingPivot) | (1 << TransformationComp_ScalingPivotInverse); - - aiMatrix4x4::Translation(ScalingPivot, chain[TransformationComp_ScalingPivot]); - aiMatrix4x4::Translation(-ScalingPivot, chain[TransformationComp_ScalingPivotInverse]); - } - - const aiVector3D& Translation = PropertyGet<aiVector3D>(props, "Lcl Translation", ok); - if (ok && Translation.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_Translation); - - aiMatrix4x4::Translation(Translation, chain[TransformationComp_Translation]); - } - - const aiVector3D& Scaling = PropertyGet<aiVector3D>(props, "Lcl Scaling", ok); - if (ok && (Scaling - all_ones).SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_Scaling); - - aiMatrix4x4::Scaling(Scaling, chain[TransformationComp_Scaling]); - } - - const aiVector3D& Rotation = PropertyGet<aiVector3D>(props, "Lcl Rotation", ok); - if (ok && Rotation.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_Rotation); - - GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]); - } - - const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>(props, "GeometricScaling", ok); - if (ok && (GeometricScaling - all_ones).SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_GeometricScaling); - aiMatrix4x4::Scaling(GeometricScaling, chain[TransformationComp_GeometricScaling]); - aiVector3D GeometricScalingInverse = GeometricScaling; - bool canscale = true; - for (unsigned int i = 0; i < 3; ++i) { - if (std::fabs(GeometricScalingInverse[i]) > zero_epsilon) { - GeometricScalingInverse[i] = 1.0f / GeometricScaling[i]; - } - else { - FBXImporter::LogError("cannot invert geometric scaling matrix with a 0.0 scale component"); - canscale = false; - break; - } - } - if (canscale) { - chainBits = chainBits | (1 << TransformationComp_GeometricScalingInverse); - aiMatrix4x4::Scaling(GeometricScalingInverse, chain[TransformationComp_GeometricScalingInverse]); - } - } - - const aiVector3D& GeometricRotation = PropertyGet<aiVector3D>(props, "GeometricRotation", ok); - if (ok && GeometricRotation.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_GeometricRotation) | (1 << TransformationComp_GeometricRotationInverse); - GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotation]); - GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotationInverse]); - chain[TransformationComp_GeometricRotationInverse].Inverse(); - } - - const aiVector3D& GeometricTranslation = PropertyGet<aiVector3D>(props, "GeometricTranslation", ok); - if (ok && GeometricTranslation.SquareLength() > zero_epsilon) { - chainBits = chainBits | (1 << TransformationComp_GeometricTranslation) | (1 << TransformationComp_GeometricTranslationInverse); - aiMatrix4x4::Translation(GeometricTranslation, chain[TransformationComp_GeometricTranslation]); - aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]); - } - - // is_complex needs to be consistent with NeedsComplexTransformationChain() - // or the interplay between this code and the animation converter would - // not be guaranteed. - //ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0)); - - // now, if we have more than just Translation, Scaling and Rotation, - // we need to generate a full node chain to accommodate for assimp's - // lack to express pivots and offsets. - if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) { - FBXImporter::LogInfo("generating full transformation chain for node: " + name); - - // query the anim_chain_bits dictionary to find out which chain elements - // have associated node animation channels. These can not be dropped - // even if they have identity transform in bind pose. - NodeAnimBitMap::const_iterator it = node_anim_chain_bits.find(name); - const unsigned int anim_chain_bitmask = (it == node_anim_chain_bits.end() ? 0 : (*it).second); - - unsigned int bit = 0x1; - for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) { - const TransformationComp comp = static_cast<TransformationComp>(i); - - if ((chainBits & bit) == 0 && (anim_chain_bitmask & bit) == 0) { - continue; - } - - if (comp == TransformationComp_PostRotation) { - chain[i] = chain[i].Inverse(); - } - - aiNode* nd = new aiNode(); - nd->mName.Set(NameTransformationChainNode(name, comp)); - nd->mTransformation = chain[i]; - - // geometric inverses go in a post-node chain - if (comp == TransformationComp_GeometricScalingInverse || - comp == TransformationComp_GeometricRotationInverse || - comp == TransformationComp_GeometricTranslationInverse - ) { - post_output_nodes.push_back(nd); - } - else { - output_nodes.push_back(nd); - } - } - - ai_assert(output_nodes.size()); - return true; - } - - // else, we can just multiply the matrices together - aiNode* nd = new aiNode(); - output_nodes.push_back(nd); - - // name passed to the method is already unique - nd->mName.Set(name); - - for (const auto &transform : chain) { - nd->mTransformation = nd->mTransformation * transform; - } - return false; - } - - void FBXConverter::SetupNodeMetadata(const Model& model, aiNode& nd) - { - const PropertyTable& props = model.Props(); - DirectPropertyMap unparsedProperties = props.GetUnparsedProperties(); - - // create metadata on node - const std::size_t numStaticMetaData = 2; - aiMetadata* data = aiMetadata::Alloc(static_cast<unsigned int>(unparsedProperties.size() + numStaticMetaData)); - nd.mMetaData = data; - int index = 0; - - // find user defined properties (3ds Max) - data->Set(index++, "UserProperties", aiString(PropertyGet<std::string>(props, "UDP3DSMAX", ""))); - // preserve the info that a node was marked as Null node in the original file. - data->Set(index++, "IsNull", model.IsNull() ? true : false); - - // add unparsed properties to the node's metadata - for (const DirectPropertyMap::value_type& prop : unparsedProperties) { - // Interpret the property as a concrete type - if (const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >()) { - data->Set(index++, prop.first, interpreted->Value()); - } - else if (const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >()) { - data->Set(index++, prop.first, interpreted->Value()); - } - else if (const TypedProperty<uint64_t>* interpreted = prop.second->As<TypedProperty<uint64_t> >()) { - data->Set(index++, prop.first, interpreted->Value()); - } - else if (const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >()) { - data->Set(index++, prop.first, interpreted->Value()); - } - else if (const TypedProperty<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >()) { - data->Set(index++, prop.first, aiString(interpreted->Value())); - } - else if (const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >()) { - data->Set(index++, prop.first, interpreted->Value()); - } - else { - ai_assert(false); - } - } - } - - void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, - const aiMatrix4x4 &absolute_transform) - { - const std::vector<const Geometry*>& geos = model.GetGeometry(); - - std::vector<unsigned int> meshes; - meshes.reserve(geos.size()); - - for (const Geometry* geo : geos) { - - const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo); - const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo); - if (mesh) { - const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, parent, root_node, - absolute_transform); - std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); - } - else if (line) { - const std::vector<unsigned int>& indices = ConvertLine(*line, model, parent, root_node); - std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); - } - else { - FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name()); - } - } - - if (meshes.size()) { - parent->mMeshes = new unsigned int[meshes.size()](); - parent->mNumMeshes = static_cast<unsigned int>(meshes.size()); - - std::swap_ranges(meshes.begin(), meshes.end(), parent->mMeshes); - } - } - - std::vector<unsigned int> - FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, - const aiMatrix4x4 &absolute_transform) - { - std::vector<unsigned int> temp; - - MeshMap::const_iterator it = meshes_converted.find(&mesh); - if (it != meshes_converted.end()) { - std::copy((*it).second.begin(), (*it).second.end(), std::back_inserter(temp)); - return temp; - } - - const std::vector<aiVector3D>& vertices = mesh.GetVertices(); - const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); - if (vertices.empty() || faces.empty()) { - FBXImporter::LogWarn("ignoring empty geometry: " + mesh.Name()); - return temp; - } - - // one material per mesh maps easily to aiMesh. Multiple material - // meshes need to be split. - const MatIndexArray& mindices = mesh.GetMaterialIndices(); - if (doc.Settings().readMaterials && !mindices.empty()) { - const MatIndexArray::value_type base = mindices[0]; - for (MatIndexArray::value_type index : mindices) { - if (index != base) { - return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform); - } - } - } - - // faster code-path, just copy the data - temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node)); - return temp; - } - - std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model, - aiNode *parent, aiNode *root_node) - { - std::vector<unsigned int> temp; - - const std::vector<aiVector3D>& vertices = line.GetVertices(); - const std::vector<int>& indices = line.GetIndices(); - if (vertices.empty() || indices.empty()) { - FBXImporter::LogWarn("ignoring empty line: " + line.Name()); - return temp; - } - - aiMesh* const out_mesh = SetupEmptyMesh(line, root_node); - out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - - // copy vertices - out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size()); - out_mesh->mVertices = new aiVector3D[out_mesh->mNumVertices]; - std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices); - - //Number of line segments (faces) is "Number of Points - Number of Endpoints" - //N.B.: Endpoints in FbxLine are denoted by negative indices. - //If such an Index is encountered, add 1 and multiply by -1 to get the real index. - unsigned int epcount = 0; - for (unsigned i = 0; i < indices.size(); i++) - { - if (indices[i] < 0) { - epcount++; - } - } - unsigned int pcount = static_cast<unsigned int>( indices.size() ); - unsigned int scount = out_mesh->mNumFaces = pcount - epcount; - - aiFace* fac = out_mesh->mFaces = new aiFace[scount](); - for (unsigned int i = 0; i < pcount; ++i) { - if (indices[i] < 0) continue; - aiFace& f = *fac++; - f.mNumIndices = 2; //2 == aiPrimitiveType_LINE - f.mIndices = new unsigned int[2]; - f.mIndices[0] = indices[i]; - int segid = indices[(i + 1 == pcount ? 0 : i + 1)]; //If we have reached he last point, wrap around - f.mIndices[1] = (segid < 0 ? (segid + 1)*-1 : segid); //Convert EndPoint Index to normal Index - } - temp.push_back(static_cast<unsigned int>(meshes.size() - 1)); - return temp; - } - - aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode *parent) - { - aiMesh* const out_mesh = new aiMesh(); - meshes.push_back(out_mesh); - meshes_converted[&mesh].push_back(static_cast<unsigned int>(meshes.size() - 1)); - - // set name - std::string name = mesh.Name(); - if (name.substr(0, 10) == "Geometry::") { - name = name.substr(10); - } - - if (name.length()) { - out_mesh->mName.Set(name); - } - else - { - out_mesh->mName = parent->mName; - } - - return out_mesh; - } - - unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, - const aiMatrix4x4 &absolute_transform, aiNode *parent, - aiNode *root_node) - { - const MatIndexArray& mindices = mesh.GetMaterialIndices(); - aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent); - - const std::vector<aiVector3D>& vertices = mesh.GetVertices(); - const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); - - // copy vertices - out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size()); - out_mesh->mVertices = new aiVector3D[vertices.size()]; - - std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices); - - // generate dummy faces - out_mesh->mNumFaces = static_cast<unsigned int>(faces.size()); - aiFace* fac = out_mesh->mFaces = new aiFace[faces.size()](); - - unsigned int cursor = 0; - for (unsigned int pcount : faces) { - aiFace& f = *fac++; - f.mNumIndices = pcount; - f.mIndices = new unsigned int[pcount]; - switch (pcount) - { - case 1: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - case 2: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - case 3: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - default: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - break; - } - for (unsigned int i = 0; i < pcount; ++i) { - f.mIndices[i] = cursor++; - } - } - - // copy normals - const std::vector<aiVector3D>& normals = mesh.GetNormals(); - if (normals.size()) { - ai_assert(normals.size() == vertices.size()); - - out_mesh->mNormals = new aiVector3D[vertices.size()]; - std::copy(normals.begin(), normals.end(), out_mesh->mNormals); - } - - // copy tangents - assimp requires both tangents and bitangents (binormals) - // to be present, or neither of them. Compute binormals from normals - // and tangents if needed. - const std::vector<aiVector3D>& tangents = mesh.GetTangents(); - const std::vector<aiVector3D>* binormals = &mesh.GetBinormals(); - - if (tangents.size()) { - std::vector<aiVector3D> tempBinormals; - if (!binormals->size()) { - if (normals.size()) { - tempBinormals.resize(normals.size()); - for (unsigned int i = 0; i < tangents.size(); ++i) { - tempBinormals[i] = normals[i] ^ tangents[i]; - } - - binormals = &tempBinormals; - } - else { - binormals = nullptr; - } - } - - if (binormals) { - ai_assert(tangents.size() == vertices.size()); - ai_assert(binormals->size() == vertices.size()); - - out_mesh->mTangents = new aiVector3D[vertices.size()]; - std::copy(tangents.begin(), tangents.end(), out_mesh->mTangents); - - out_mesh->mBitangents = new aiVector3D[vertices.size()]; - std::copy(binormals->begin(), binormals->end(), out_mesh->mBitangents); - } - } - - // copy texture coords - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i); - if (uvs.empty()) { - break; - } - - aiVector3D* out_uv = out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()]; - for (const aiVector2D& v : uvs) { - *out_uv++ = aiVector3D(v.x, v.y, 0.0f); - } - - out_mesh->mNumUVComponents[i] = 2; - } - - // copy vertex colors - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { - const std::vector<aiColor4D>& colors = mesh.GetVertexColors(i); - if (colors.empty()) { - break; - } - - out_mesh->mColors[i] = new aiColor4D[vertices.size()]; - std::copy(colors.begin(), colors.end(), out_mesh->mColors[i]); - } - - if (!doc.Settings().readMaterials || mindices.empty()) { - FBXImporter::LogError("no material assigned to mesh, setting default material"); - out_mesh->mMaterialIndex = GetDefaultMaterial(); - } - else { - ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]); - } - - if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) { - ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, NO_MATERIAL_SEPARATION, - nullptr); - } - - std::vector<aiAnimMesh*> animMeshes; - for (const BlendShape* blendShape : mesh.GetBlendShapes()) { - for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) { - const std::vector<const ShapeGeometry*>& shapeGeometries = blendShapeChannel->GetShapeGeometries(); - for (size_t i = 0; i < shapeGeometries.size(); i++) { - aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh); - const ShapeGeometry* shapeGeometry = shapeGeometries.at(i); - const std::vector<aiVector3D>& vertices = shapeGeometry->GetVertices(); - const std::vector<aiVector3D>& normals = shapeGeometry->GetNormals(); - const std::vector<unsigned int>& indices = shapeGeometry->GetIndices(); - animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name())); - for (size_t j = 0; j < indices.size(); j++) { - unsigned int index = indices.at(j); - aiVector3D vertex = vertices.at(j); - aiVector3D normal = normals.at(j); - unsigned int count = 0; - const unsigned int* outIndices = mesh.ToOutputVertexIndex(index, count); - for (unsigned int k = 0; k < count; k++) { - unsigned int index = outIndices[k]; - animMesh->mVertices[index] += vertex; - if (animMesh->mNormals != nullptr) { - animMesh->mNormals[index] += normal; - animMesh->mNormals[index].NormalizeSafe(); - } - } - } - animMesh->mWeight = shapeGeometries.size() > 1 ? blendShapeChannel->DeformPercent() / 100.0f : 1.0f; - animMeshes.push_back(animMesh); - } - } - } - const size_t numAnimMeshes = animMeshes.size(); - if (numAnimMeshes > 0) { - out_mesh->mNumAnimMeshes = static_cast<unsigned int>(numAnimMeshes); - out_mesh->mAnimMeshes = new aiAnimMesh*[numAnimMeshes]; - for (size_t i = 0; i < numAnimMeshes; i++) { - out_mesh->mAnimMeshes[i] = animMeshes.at(i); - } - } - return static_cast<unsigned int>(meshes.size() - 1); - } - - std::vector<unsigned int> - FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, - aiNode *root_node, - const aiMatrix4x4 &absolute_transform) - { - const MatIndexArray& mindices = mesh.GetMaterialIndices(); - ai_assert(mindices.size()); - - std::set<MatIndexArray::value_type> had; - std::vector<unsigned int> indices; - - for (MatIndexArray::value_type index : mindices) { - if (had.find(index) == had.end()) { - - indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform)); - had.insert(index); - } - } - - return indices; - } - - unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, - MatIndexArray::value_type index, - aiNode *parent, aiNode *root_node, - const aiMatrix4x4 &absolute_transform) - { - aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent); - - const MatIndexArray& mindices = mesh.GetMaterialIndices(); - const std::vector<aiVector3D>& vertices = mesh.GetVertices(); - const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); - - const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != nullptr; - - unsigned int count_faces = 0; - unsigned int count_vertices = 0; - - // count faces - std::vector<unsigned int>::const_iterator itf = faces.begin(); - for (MatIndexArray::const_iterator it = mindices.begin(), - end = mindices.end(); it != end; ++it, ++itf) - { - if ((*it) != index) { - continue; - } - ++count_faces; - count_vertices += *itf; - } - - ai_assert(count_faces); - ai_assert(count_vertices); - - // mapping from output indices to DOM indexing, needed to resolve weights or blendshapes - std::vector<unsigned int> reverseMapping; - std::map<unsigned int, unsigned int> translateIndexMap; - if (process_weights || mesh.GetBlendShapes().size() > 0) { - reverseMapping.resize(count_vertices); - } - - // allocate output data arrays, but don't fill them yet - out_mesh->mNumVertices = count_vertices; - out_mesh->mVertices = new aiVector3D[count_vertices]; - - out_mesh->mNumFaces = count_faces; - aiFace* fac = out_mesh->mFaces = new aiFace[count_faces](); - - - // allocate normals - const std::vector<aiVector3D>& normals = mesh.GetNormals(); - if (normals.size()) { - ai_assert(normals.size() == vertices.size()); - out_mesh->mNormals = new aiVector3D[vertices.size()]; - } - - // allocate tangents, binormals. - const std::vector<aiVector3D>& tangents = mesh.GetTangents(); - const std::vector<aiVector3D>* binormals = &mesh.GetBinormals(); - std::vector<aiVector3D> tempBinormals; - - if (tangents.size()) { - if (!binormals->size()) { - if (normals.size()) { - // XXX this computes the binormals for the entire mesh, not only - // the part for which we need them. - tempBinormals.resize(normals.size()); - for (unsigned int i = 0; i < tangents.size(); ++i) { - tempBinormals[i] = normals[i] ^ tangents[i]; - } - - binormals = &tempBinormals; - } - else { - binormals = nullptr; - } - } - - if (binormals) { - ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size()); - - out_mesh->mTangents = new aiVector3D[vertices.size()]; - out_mesh->mBitangents = new aiVector3D[vertices.size()]; - } - } - - // allocate texture coords - unsigned int num_uvs = 0; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i, ++num_uvs) { - const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i); - if (uvs.empty()) { - break; - } - - out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()]; - out_mesh->mNumUVComponents[i] = 2; - } - - // allocate vertex colors - unsigned int num_vcs = 0; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i, ++num_vcs) { - const std::vector<aiColor4D>& colors = mesh.GetVertexColors(i); - if (colors.empty()) { - break; - } - - out_mesh->mColors[i] = new aiColor4D[vertices.size()]; - } - - unsigned int cursor = 0, in_cursor = 0; - - itf = faces.begin(); - for (MatIndexArray::const_iterator it = mindices.begin(), end = mindices.end(); it != end; ++it, ++itf) - { - const unsigned int pcount = *itf; - if ((*it) != index) { - in_cursor += pcount; - continue; - } - - aiFace& f = *fac++; - - f.mNumIndices = pcount; - f.mIndices = new unsigned int[pcount]; - switch (pcount) - { - case 1: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - case 2: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - case 3: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - default: - out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - break; - } - for (unsigned int i = 0; i < pcount; ++i, ++cursor, ++in_cursor) { - f.mIndices[i] = cursor; - - if (reverseMapping.size()) { - reverseMapping[cursor] = in_cursor; - translateIndexMap[in_cursor] = cursor; - } - - out_mesh->mVertices[cursor] = vertices[in_cursor]; - - if (out_mesh->mNormals) { - out_mesh->mNormals[cursor] = normals[in_cursor]; - } - - if (out_mesh->mTangents) { - out_mesh->mTangents[cursor] = tangents[in_cursor]; - out_mesh->mBitangents[cursor] = (*binormals)[in_cursor]; - } - - for (unsigned int j = 0; j < num_uvs; ++j) { - const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(j); - out_mesh->mTextureCoords[j][cursor] = aiVector3D(uvs[in_cursor].x, uvs[in_cursor].y, 0.0f); - } - - for (unsigned int j = 0; j < num_vcs; ++j) { - const std::vector<aiColor4D>& cols = mesh.GetVertexColors(j); - out_mesh->mColors[j][cursor] = cols[in_cursor]; - } - } - } - - ConvertMaterialForMesh(out_mesh, model, mesh, index); - - if (process_weights) { - ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, index, &reverseMapping); - } - - std::vector<aiAnimMesh*> animMeshes; - for (const BlendShape* blendShape : mesh.GetBlendShapes()) { - for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) { - const std::vector<const ShapeGeometry*>& shapeGeometries = blendShapeChannel->GetShapeGeometries(); - for (size_t i = 0; i < shapeGeometries.size(); i++) { - aiAnimMesh* animMesh = aiCreateAnimMesh(out_mesh); - const ShapeGeometry* shapeGeometry = shapeGeometries.at(i); - const std::vector<aiVector3D>& vertices = shapeGeometry->GetVertices(); - const std::vector<aiVector3D>& normals = shapeGeometry->GetNormals(); - const std::vector<unsigned int>& indices = shapeGeometry->GetIndices(); - animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name())); - for (size_t j = 0; j < indices.size(); j++) { - unsigned int index = indices.at(j); - aiVector3D vertex = vertices.at(j); - aiVector3D normal = normals.at(j); - unsigned int count = 0; - const unsigned int* outIndices = mesh.ToOutputVertexIndex(index, count); - for (unsigned int k = 0; k < count; k++) { - unsigned int outIndex = outIndices[k]; - if (translateIndexMap.find(outIndex) == translateIndexMap.end()) - continue; - unsigned int index = translateIndexMap[outIndex]; - animMesh->mVertices[index] += vertex; - if (animMesh->mNormals != nullptr) { - animMesh->mNormals[index] += normal; - animMesh->mNormals[index].NormalizeSafe(); - } - } - } - animMesh->mWeight = shapeGeometries.size() > 1 ? blendShapeChannel->DeformPercent() / 100.0f : 1.0f; - animMeshes.push_back(animMesh); - } - } - } - - const size_t numAnimMeshes = animMeshes.size(); - if (numAnimMeshes > 0) { - out_mesh->mNumAnimMeshes = static_cast<unsigned int>(numAnimMeshes); - out_mesh->mAnimMeshes = new aiAnimMesh*[numAnimMeshes]; - for (size_t i = 0; i < numAnimMeshes; i++) { - out_mesh->mAnimMeshes[i] = animMeshes.at(i); - } - } - - return static_cast<unsigned int>(meshes.size() - 1); - } - - void FBXConverter::ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, - const aiMatrix4x4 &absolute_transform, - aiNode *parent, aiNode *root_node, unsigned int materialIndex, - std::vector<unsigned int> *outputVertStartIndices) - { - ai_assert(geo.DeformerSkin()); - - std::vector<size_t> out_indices; - std::vector<size_t> index_out_indices; - std::vector<size_t> count_out_indices; - - const Skin& sk = *geo.DeformerSkin(); - - std::vector<aiBone*> bones; - - const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION; - ai_assert(no_mat_check || outputVertStartIndices); - - try { - // iterate over the sub deformers - for (const Cluster* cluster : sk.Clusters()) { - ai_assert(cluster); - - const WeightIndexArray& indices = cluster->GetIndices(); - - const MatIndexArray& mats = geo.GetMaterialIndices(); - - const size_t no_index_sentinel = std::numeric_limits<size_t>::max(); - - count_out_indices.clear(); - index_out_indices.clear(); - out_indices.clear(); - - - // now check if *any* of these weights is contained in the output mesh, - // taking notes so we don't need to do it twice. - for (WeightIndexArray::value_type index : indices) { - - unsigned int count = 0; - const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count); - // ToOutputVertexIndex only returns nullptr if index is out of bounds - // which should never happen - ai_assert(out_idx != nullptr); - - index_out_indices.push_back(no_index_sentinel); - count_out_indices.push_back(0); - - for (unsigned int i = 0; i < count; ++i) { - if (no_mat_check || static_cast<size_t>(mats[geo.FaceForVertexIndex(out_idx[i])]) == materialIndex) { - - if (index_out_indices.back() == no_index_sentinel) { - index_out_indices.back() = out_indices.size(); - } - - if (no_mat_check) { - out_indices.push_back(out_idx[i]); - } else { - // this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn) - const std::vector<unsigned int>::iterator it = std::lower_bound( - outputVertStartIndices->begin(), - outputVertStartIndices->end(), - out_idx[i] - ); - - out_indices.push_back(std::distance(outputVertStartIndices->begin(), it)); - } - - ++count_out_indices.back(); - } - } - } - - // if we found at least one, generate the output bones - // XXX this could be heavily simplified by collecting the bone - // data in a single step. - ConvertCluster(bones, cluster, out_indices, index_out_indices, - count_out_indices, absolute_transform, parent, root_node); - } - - bone_map.clear(); - } - catch (std::exception&e) { - std::for_each(bones.begin(), bones.end(), Util::delete_fun<aiBone>()); - throw; - } - - if (bones.empty()) { - out->mBones = nullptr; - out->mNumBones = 0; - return; - } else { - out->mBones = new aiBone *[bones.size()](); - out->mNumBones = static_cast<unsigned int>(bones.size()); - - std::swap_ranges(bones.begin(), bones.end(), out->mBones); - } - } - - const aiNode* FBXConverter::GetNodeByName( const aiString& name, aiNode *current_node ) - { - aiNode * iter = current_node; - //printf("Child count: %d", iter->mNumChildren); - return iter; - } - - void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl, - std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices, - std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, - aiNode *parent, aiNode *root_node) { - ai_assert(cl); // make sure cluster valid - std::string deformer_name = cl->TargetNode()->Name(); - aiString bone_name = aiString(FixNodeName(deformer_name)); - - aiBone *bone = nullptr; - - if (bone_map.count(deformer_name)) { - std::cout << "retrieved bone from lookup " << bone_name.C_Str() << ". Deformer: " << deformer_name - << std::endl; - bone = bone_map[deformer_name]; - } else { - std::cout << "created new bone " << bone_name.C_Str() << ". Deformer: " << deformer_name << std::endl; - bone = new aiBone(); - bone->mName = bone_name; - - // store local transform link for post processing - bone->mOffsetMatrix = cl->TransformLink(); - bone->mOffsetMatrix.Inverse(); - - aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform; - - bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset - - - // - // Now calculate the aiVertexWeights - // - - aiVertexWeight *cursor = nullptr; - - bone->mNumWeights = static_cast<unsigned int>(out_indices.size()); - cursor = bone->mWeights = new aiVertexWeight[out_indices.size()]; - - const size_t no_index_sentinel = std::numeric_limits<size_t>::max(); - const WeightArray& weights = cl->GetWeights(); - - const size_t c = index_out_indices.size(); - for (size_t i = 0; i < c; ++i) { - const size_t index_index = index_out_indices[i]; - - if (index_index == no_index_sentinel) { - continue; - } - - const size_t cc = count_out_indices[i]; - for (size_t j = 0; j < cc; ++j) { - // cursor runs from first element relative to the start - // or relative to the start of the next indexes. - aiVertexWeight& out_weight = *cursor++; - - out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]); - out_weight.mWeight = weights[i]; - } - } - - bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone)); - } - - std::cout << "bone research: Indicies size: " << out_indices.size() << std::endl; - - // lookup must be populated in case something goes wrong - // this also allocates bones to mesh instance outside - local_mesh_bones.push_back(bone); - } - - void FBXConverter::ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo, - MatIndexArray::value_type materialIndex) - { - // locate source materials for this mesh - const std::vector<const Material*>& mats = model.GetMaterials(); - if (static_cast<unsigned int>(materialIndex) >= mats.size() || materialIndex < 0) { - FBXImporter::LogError("material index out of bounds, setting default material"); - out->mMaterialIndex = GetDefaultMaterial(); - return; - } - - const Material* const mat = mats[materialIndex]; - MaterialMap::const_iterator it = materials_converted.find(mat); - if (it != materials_converted.end()) { - out->mMaterialIndex = (*it).second; - return; - } - - out->mMaterialIndex = ConvertMaterial(*mat, &geo); - materials_converted[mat] = out->mMaterialIndex; - } - - unsigned int FBXConverter::GetDefaultMaterial() - { - if (defaultMaterialIndex) { - return defaultMaterialIndex - 1; - } - - aiMaterial* out_mat = new aiMaterial(); - materials.push_back(out_mat); - - const aiColor3D diffuse = aiColor3D(0.8f, 0.8f, 0.8f); - out_mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - - aiString s; - s.Set(AI_DEFAULT_MATERIAL_NAME); - - out_mat->AddProperty(&s, AI_MATKEY_NAME); - - defaultMaterialIndex = static_cast<unsigned int>(materials.size()); - return defaultMaterialIndex - 1; - } - - - unsigned int FBXConverter::ConvertMaterial(const Material& material, const MeshGeometry* const mesh) - { - const PropertyTable& props = material.Props(); - - // generate empty output material - aiMaterial* out_mat = new aiMaterial(); - materials_converted[&material] = static_cast<unsigned int>(materials.size()); - - materials.push_back(out_mat); - - aiString str; - - // strip Material:: prefix - std::string name = material.Name(); - if (name.substr(0, 10) == "Material::") { - name = name.substr(10); - } - - // set material name if not empty - this could happen - // and there should be no key for it in this case. - if (name.length()) { - str.Set(name); - out_mat->AddProperty(&str, AI_MATKEY_NAME); - } - - // Set the shading mode as best we can: The FBX specification only mentions Lambert and Phong, and only Phong is mentioned in Assimp's aiShadingMode enum. - if (material.GetShadingModel() == "phong") - { - aiShadingMode shadingMode = aiShadingMode_Phong; - out_mat->AddProperty<aiShadingMode>(&shadingMode, 1, AI_MATKEY_SHADING_MODEL); - } - - // shading stuff and colors - SetShadingPropertiesCommon(out_mat, props); - SetShadingPropertiesRaw( out_mat, props, material.Textures(), mesh ); - - // texture assignments - SetTextureProperties(out_mat, material.Textures(), mesh); - SetTextureProperties(out_mat, material.LayeredTextures(), mesh); - - return static_cast<unsigned int>(materials.size() - 1); - } - - unsigned int FBXConverter::ConvertVideo(const Video& video) - { - // generate empty output texture - aiTexture* out_tex = new aiTexture(); - textures.push_back(out_tex); - - // assuming the texture is compressed - out_tex->mWidth = static_cast<unsigned int>(video.ContentLength()); // total data size - out_tex->mHeight = 0; // fixed to 0 - - // steal the data from the Video to avoid an additional copy - out_tex->pcData = reinterpret_cast<aiTexel*>(const_cast<Video&>(video).RelinquishContent()); - - // try to extract a hint from the file extension - const std::string& filename = video.RelativeFilename().empty() ? video.FileName() : video.RelativeFilename(); - std::string ext = BaseImporter::GetExtension(filename); - - if (ext == "jpeg") { - ext = "jpg"; - } - - if (ext.size() <= 3) { - memcpy(out_tex->achFormatHint, ext.c_str(), ext.size()); - } - - out_tex->mFilename.Set(filename.c_str()); - - return static_cast<unsigned int>(textures.size() - 1); - } - - aiString FBXConverter::GetTexturePath(const Texture* tex) - { - aiString path; - path.Set(tex->RelativeFilename()); - - const Video* media = tex->Media(); - if (media != nullptr) { - bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found) - unsigned int index; - - VideoMap::const_iterator it = textures_converted.find(*media); - if (it != textures_converted.end()) { - index = (*it).second; - textureReady = true; - } - else { - if (media->ContentLength() > 0) { - index = ConvertVideo(*media); - textures_converted[*media] = index; - textureReady = true; - } - } - - // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready - if (doc.Settings().useLegacyEmbeddedTextureNaming) { - if (textureReady) { - // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" - // In FBX files textures are now stored internally by Assimp with their filename included - // Now Assimp can lookup through the loaded textures after all data is processed - // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it - // This may occur on this case too, it has to be studied - path.data[0] = '*'; - path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index); - } - } - } - - return path; - } - - void FBXConverter::TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, - const std::string& propName, - aiTextureType target, const MeshGeometry* const mesh) { - TextureMap::const_iterator it = textures.find(propName); - if (it == textures.end()) { - return; - } - - const Texture* const tex = (*it).second; - if (tex != 0) - { - aiString path = GetTexturePath(tex); - out_mat->AddProperty(&path, _AI_MATKEY_TEXTURE_BASE, target, 0); - - aiUVTransform uvTrafo; - // XXX handle all kinds of UV transformations - uvTrafo.mScaling = tex->UVScaling(); - uvTrafo.mTranslation = tex->UVTranslation(); - out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0); - - const PropertyTable& props = tex->Props(); - - int uvIndex = 0; - - bool ok; - const std::string& uvSet = PropertyGet<std::string>(props, "UVSet", ok); - if (ok) { - // "default" is the name which usually appears in the FbxFileTexture template - if (uvSet != "default" && uvSet.length()) { - // this is a bit awkward - we need to find a mesh that uses this - // material and scan its UV channels for the given UV name because - // assimp references UV channels by index, not by name. - - // XXX: the case that UV channels may appear in different orders - // in meshes is unhandled. A possible solution would be to sort - // the UV channels alphabetically, but this would have the side - // effect that the primary (first) UV channel would sometimes - // be moved, causing trouble when users read only the first - // UV channel and ignore UV channel assignments altogether. - - const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), - std::find(materials.begin(), materials.end(), out_mat) - )); - - - uvIndex = -1; - if (!mesh) - { - for (const MeshMap::value_type& v : meshes_converted) { - const MeshGeometry* const meshGeom = dynamic_cast<const MeshGeometry*> (v.first); - if (!meshGeom) { - continue; - } - - const MatIndexArray& mats = meshGeom->GetMaterialIndices(); - if (std::find(mats.begin(), mats.end(), matIndex) == mats.end()) { - continue; - } - - int index = -1; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (meshGeom->GetTextureCoords(i).empty()) { - break; - } - const std::string& name = meshGeom->GetTextureCoordChannelName(i); - if (name == uvSet) { - index = static_cast<int>(i); - break; - } - } - if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); - continue; - } - - if (uvIndex == -1) { - uvIndex = index; - } - else { - FBXImporter::LogWarn("the UV channel named " + uvSet + - " appears at different positions in meshes, results will be wrong"); - } - } - } - else - { - int index = -1; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (mesh->GetTextureCoords(i).empty()) { - break; - } - const std::string& name = mesh->GetTextureCoordChannelName(i); - if (name == uvSet) { - index = static_cast<int>(i); - break; - } - } - if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); - } - - if (uvIndex == -1) { - uvIndex = index; - } - } - - if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); - uvIndex = 0; - } - } - } - - out_mat->AddProperty(&uvIndex, 1, _AI_MATKEY_UVWSRC_BASE, target, 0); - } - } - - void FBXConverter::TrySetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, - const std::string& propName, - aiTextureType target, const MeshGeometry* const mesh) { - LayeredTextureMap::const_iterator it = layeredTextures.find(propName); - if (it == layeredTextures.end()) { - return; - } - - int texCount = (*it).second->textureCount(); - - // Set the blend mode for layered textures - int blendmode = (*it).second->GetBlendMode(); - out_mat->AddProperty(&blendmode, 1, _AI_MATKEY_TEXOP_BASE, target, 0); - - for (int texIndex = 0; texIndex < texCount; texIndex++) { - - const Texture* const tex = (*it).second->getTexture(texIndex); - - aiString path = GetTexturePath(tex); - out_mat->AddProperty(&path, _AI_MATKEY_TEXTURE_BASE, target, texIndex); - - aiUVTransform uvTrafo; - // XXX handle all kinds of UV transformations - uvTrafo.mScaling = tex->UVScaling(); - uvTrafo.mTranslation = tex->UVTranslation(); - out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex); - - const PropertyTable& props = tex->Props(); - - int uvIndex = 0; - - bool ok; - const std::string& uvSet = PropertyGet<std::string>(props, "UVSet", ok); - if (ok) { - // "default" is the name which usually appears in the FbxFileTexture template - if (uvSet != "default" && uvSet.length()) { - // this is a bit awkward - we need to find a mesh that uses this - // material and scan its UV channels for the given UV name because - // assimp references UV channels by index, not by name. - - // XXX: the case that UV channels may appear in different orders - // in meshes is unhandled. A possible solution would be to sort - // the UV channels alphabetically, but this would have the side - // effect that the primary (first) UV channel would sometimes - // be moved, causing trouble when users read only the first - // UV channel and ignore UV channel assignments altogether. - - const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), - std::find(materials.begin(), materials.end(), out_mat) - )); - - uvIndex = -1; - if (!mesh) - { - for (const MeshMap::value_type& v : meshes_converted) { - const MeshGeometry* const meshGeom = dynamic_cast<const MeshGeometry*> (v.first); - if (!meshGeom) { - continue; - } - - const MatIndexArray& mats = meshGeom->GetMaterialIndices(); - if (std::find(mats.begin(), mats.end(), matIndex) == mats.end()) { - continue; - } - - int index = -1; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (meshGeom->GetTextureCoords(i).empty()) { - break; - } - const std::string& name = meshGeom->GetTextureCoordChannelName(i); - if (name == uvSet) { - index = static_cast<int>(i); - break; - } - } - if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); - continue; - } - - if (uvIndex == -1) { - uvIndex = index; - } - else { - FBXImporter::LogWarn("the UV channel named " + uvSet + - " appears at different positions in meshes, results will be wrong"); - } - } - } - else - { - int index = -1; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (mesh->GetTextureCoords(i).empty()) { - break; - } - const std::string& name = mesh->GetTextureCoordChannelName(i); - if (name == uvSet) { - index = static_cast<int>(i); - break; - } - } - if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); - } - - if (uvIndex == -1) { - uvIndex = index; - } - } - - if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); - uvIndex = 0; - } - } - } - - out_mat->AddProperty(&uvIndex, 1, _AI_MATKEY_UVWSRC_BASE, target, texIndex); - } - } - - void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh) - { - TrySetTextureProperties(out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh); - TrySetTextureProperties(out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh); - TrySetTextureProperties(out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE, mesh); - TrySetTextureProperties(out_mat, textures, "SpecularColor", aiTextureType_SPECULAR, mesh); - TrySetTextureProperties(out_mat, textures, "SpecularFactor", aiTextureType_SPECULAR, mesh); - TrySetTextureProperties(out_mat, textures, "TransparentColor", aiTextureType_OPACITY, mesh); - TrySetTextureProperties(out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION, mesh); - TrySetTextureProperties(out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh); - TrySetTextureProperties(out_mat, textures, "NormalMap", aiTextureType_NORMALS, mesh); - TrySetTextureProperties(out_mat, textures, "Bump", aiTextureType_HEIGHT, mesh); - TrySetTextureProperties(out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh); - TrySetTextureProperties( out_mat, textures, "TransparencyFactor", aiTextureType_OPACITY, mesh ); - TrySetTextureProperties( out_mat, textures, "EmissiveFactor", aiTextureType_EMISSIVE, mesh ); - //Maya counterparts - TrySetTextureProperties(out_mat, textures, "Maya|DiffuseTexture", aiTextureType_DIFFUSE, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|NormalTexture", aiTextureType_NORMALS, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh); - - // Maya PBR - TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh); - - // Maya stingray - TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh); - TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh); - } - - void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh) - { - TrySetTextureProperties(out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "EmissiveColor", aiTextureType_EMISSIVE, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "SpecularColor", aiTextureType_SPECULAR, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "SpecularFactor", aiTextureType_SPECULAR, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "TransparentColor", aiTextureType_OPACITY, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "ReflectionColor", aiTextureType_REFLECTION, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "NormalMap", aiTextureType_NORMALS, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "Bump", aiTextureType_HEIGHT, mesh); - TrySetTextureProperties(out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh); - TrySetTextureProperties( out_mat, layeredTextures, "EmissiveFactor", aiTextureType_EMISSIVE, mesh ); - TrySetTextureProperties( out_mat, layeredTextures, "TransparencyFactor", aiTextureType_OPACITY, mesh ); - } - - aiColor3D FBXConverter::GetColorPropertyFactored(const PropertyTable& props, const std::string& colorName, - const std::string& factorName, bool& result, bool useTemplate) - { - result = true; - - bool ok; - aiVector3D BaseColor = PropertyGet<aiVector3D>(props, colorName, ok, useTemplate); - if (!ok) { - result = false; - return aiColor3D(0.0f, 0.0f, 0.0f); - } - - // if no factor name, return the colour as is - if (factorName.empty()) { - return aiColor3D(BaseColor.x, BaseColor.y, BaseColor.z); - } - - // otherwise it should be multiplied by the factor, if found. - float factor = PropertyGet<float>(props, factorName, ok, useTemplate); - if (ok) { - BaseColor *= factor; - } - return aiColor3D(BaseColor.x, BaseColor.y, BaseColor.z); - } - - aiColor3D FBXConverter::GetColorPropertyFromMaterial(const PropertyTable& props, const std::string& baseName, - bool& result) - { - return GetColorPropertyFactored(props, baseName + "Color", baseName + "Factor", result, true); - } - - aiColor3D FBXConverter::GetColorProperty(const PropertyTable& props, const std::string& colorName, - bool& result, bool useTemplate) - { - result = true; - bool ok; - const aiVector3D& ColorVec = PropertyGet<aiVector3D>(props, colorName, ok, useTemplate); - if (!ok) { - result = false; - return aiColor3D(0.0f, 0.0f, 0.0f); - } - return aiColor3D(ColorVec.x, ColorVec.y, ColorVec.z); - } - - void FBXConverter::SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props) - { - // Set shading properties. - // Modern FBX Files have two separate systems for defining these, - // with only the more comprehensive one described in the property template. - // Likely the other values are a legacy system, - // which is still always exported by the official FBX SDK. - // - // Blender's FBX import and export mostly ignore this legacy system, - // and as we only support recent versions of FBX anyway, we can do the same. - bool ok; - - const aiColor3D& Diffuse = GetColorPropertyFromMaterial(props, "Diffuse", ok); - if (ok) { - out_mat->AddProperty(&Diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - } - - const aiColor3D& Emissive = GetColorPropertyFromMaterial(props, "Emissive", ok); - if (ok) { - out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE); - } - - const aiColor3D& Ambient = GetColorPropertyFromMaterial(props, "Ambient", ok); - if (ok) { - out_mat->AddProperty(&Ambient, 1, AI_MATKEY_COLOR_AMBIENT); - } - - // we store specular factor as SHININESS_STRENGTH, so just get the color - const aiColor3D& Specular = GetColorProperty(props, "SpecularColor", ok, true); - if (ok) { - out_mat->AddProperty(&Specular, 1, AI_MATKEY_COLOR_SPECULAR); - } - - // and also try to get SHININESS_STRENGTH - const float SpecularFactor = PropertyGet<float>(props, "SpecularFactor", ok, true); - if (ok) { - out_mat->AddProperty(&SpecularFactor, 1, AI_MATKEY_SHININESS_STRENGTH); - } - - // and the specular exponent - const float ShininessExponent = PropertyGet<float>(props, "ShininessExponent", ok); - if (ok) { - out_mat->AddProperty(&ShininessExponent, 1, AI_MATKEY_SHININESS); - } - - // TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes: - const aiColor3D& Transparent = GetColorPropertyFactored(props, "TransparentColor", "TransparencyFactor", ok); - float CalculatedOpacity = 1.0f; - if (ok) { - out_mat->AddProperty(&Transparent, 1, AI_MATKEY_COLOR_TRANSPARENT); - // as calculated by FBX SDK 2017: - CalculatedOpacity = 1.0f - ((Transparent.r + Transparent.g + Transparent.b) / 3.0f); - } - - // try to get the transparency factor - const float TransparencyFactor = PropertyGet<float>(props, "TransparencyFactor", ok); - if (ok) { - out_mat->AddProperty(&TransparencyFactor, 1, AI_MATKEY_TRANSPARENCYFACTOR); - } - - // use of TransparencyFactor is inconsistent. - // Maya always stores it as 1.0, - // so we can't use it to set AI_MATKEY_OPACITY. - // Blender is more sensible and stores it as the alpha value. - // However both the FBX SDK and Blender always write an additional - // legacy "Opacity" field, so we can try to use that. - // - // If we can't find it, - // we can fall back to the value which the FBX SDK calculates - // from transparency colour (RGB) and factor (F) as - // 1.0 - F*((R+G+B)/3). - // - // There's no consistent way to interpret this opacity value, - // so it's up to clients to do the correct thing. - const float Opacity = PropertyGet<float>(props, "Opacity", ok); - if (ok) { - out_mat->AddProperty(&Opacity, 1, AI_MATKEY_OPACITY); - } - else if (CalculatedOpacity != 1.0) { - out_mat->AddProperty(&CalculatedOpacity, 1, AI_MATKEY_OPACITY); - } - - // reflection color and factor are stored separately - const aiColor3D& Reflection = GetColorProperty(props, "ReflectionColor", ok, true); - if (ok) { - out_mat->AddProperty(&Reflection, 1, AI_MATKEY_COLOR_REFLECTIVE); - } - - float ReflectionFactor = PropertyGet<float>(props, "ReflectionFactor", ok, true); - if (ok) { - out_mat->AddProperty(&ReflectionFactor, 1, AI_MATKEY_REFLECTIVITY); - } - - const float BumpFactor = PropertyGet<float>(props, "BumpFactor", ok); - if (ok) { - out_mat->AddProperty(&BumpFactor, 1, AI_MATKEY_BUMPSCALING); - } - - const float DispFactor = PropertyGet<float>(props, "DisplacementFactor", ok); - if (ok) { - out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0); - } -} - - -void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTable& props, const TextureMap& textures, const MeshGeometry* const mesh) -{ - // Add all the unparsed properties with a "$raw." prefix - - const std::string prefix = "$raw."; - - for (const DirectPropertyMap::value_type& prop : props.GetUnparsedProperties()) { - - std::string name = prefix + prop.first; - - if (const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >()) - { - out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0); - } - else if (const TypedProperty<aiColor3D>* interpreted = prop.second->As<TypedProperty<aiColor3D> >()) - { - out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0); - } - else if (const TypedProperty<aiColor4D>* interpreted = prop.second->As<TypedProperty<aiColor4D> >()) - { - out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0); - } - else if (const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >()) - { - out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0); - } - else if (const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >()) - { - out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0); - } - else if (const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >()) - { - int value = interpreted->Value() ? 1 : 0; - out_mat->AddProperty(&value, 1, name.c_str(), 0, 0); - } - else if (const TypedProperty<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >()) - { - const aiString value = aiString(interpreted->Value()); - out_mat->AddProperty(&value, name.c_str(), 0, 0); - } - } - - // Add the textures' properties - - for (TextureMap::const_iterator it = textures.begin(); it != textures.end(); it++) { - - std::string name = prefix + it->first; - - const Texture* const tex = (*it).second; - if (tex != nullptr) - { - aiString path; - path.Set(tex->RelativeFilename()); - - const Video* media = tex->Media(); - if (media != nullptr && media->ContentLength() > 0) { - unsigned int index; - - VideoMap::const_iterator it = textures_converted.find(*media); - if (it != textures_converted.end()) { - index = (*it).second; - } - else { - index = ConvertVideo(*media); - textures_converted[*media] = index; - } - - // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) - path.data[0] = '*'; - path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index); - } - - out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0); - - aiUVTransform uvTrafo; - // XXX handle all kinds of UV transformations - uvTrafo.mScaling = tex->UVScaling(); - uvTrafo.mTranslation = tex->UVTranslation(); - out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0); - - int uvIndex = 0; - - bool uvFound = false; - const std::string& uvSet = PropertyGet<std::string>(tex->Props(), "UVSet", uvFound); - if (uvFound) { - // "default" is the name which usually appears in the FbxFileTexture template - if (uvSet != "default" && uvSet.length()) { - // this is a bit awkward - we need to find a mesh that uses this - // material and scan its UV channels for the given UV name because - // assimp references UV channels by index, not by name. - - // XXX: the case that UV channels may appear in different orders - // in meshes is unhandled. A possible solution would be to sort - // the UV channels alphabetically, but this would have the side - // effect that the primary (first) UV channel would sometimes - // be moved, causing trouble when users read only the first - // UV channel and ignore UV channel assignments altogether. - - std::vector<aiMaterial*>::iterator materialIt = std::find(materials.begin(), materials.end(), out_mat); - const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), materialIt)); - - uvIndex = -1; - if (!mesh) - { - for (const MeshMap::value_type& v : meshes_converted) { - const MeshGeometry* const meshGeom = dynamic_cast<const MeshGeometry*>(v.first); - if (!meshGeom) { - continue; - } - - const MatIndexArray& mats = meshGeom->GetMaterialIndices(); - if (std::find(mats.begin(), mats.end(), matIndex) == mats.end()) { - continue; - } - - int index = -1; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (meshGeom->GetTextureCoords(i).empty()) { - break; - } - const std::string& name = meshGeom->GetTextureCoordChannelName(i); - if (name == uvSet) { - index = static_cast<int>(i); - break; - } - } - if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); - continue; - } - - if (uvIndex == -1) { - uvIndex = index; - } - else { - FBXImporter::LogWarn("the UV channel named " + uvSet + " appears at different positions in meshes, results will be wrong"); - } - } - } - else - { - int index = -1; - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (mesh->GetTextureCoords(i).empty()) { - break; - } - const std::string& name = mesh->GetTextureCoordChannelName(i); - if (name == uvSet) { - index = static_cast<int>(i); - break; - } - } - if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); - } - - if (uvIndex == -1) { - uvIndex = index; - } - } - - if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); - uvIndex = 0; - } - } - } - - out_mat->AddProperty(&uvIndex, 1, (name + "|uvwsrc").c_str(), aiTextureType_UNKNOWN, 0); - } - } - } - - - double FBXConverter::FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal) { - switch (fp) { - case FileGlobalSettings::FrameRate_DEFAULT: - return 1.0; - - case FileGlobalSettings::FrameRate_120: - return 120.0; - - case FileGlobalSettings::FrameRate_100: - return 100.0; - - case FileGlobalSettings::FrameRate_60: - return 60.0; - - case FileGlobalSettings::FrameRate_50: - return 50.0; - - case FileGlobalSettings::FrameRate_48: - return 48.0; - - case FileGlobalSettings::FrameRate_30: - case FileGlobalSettings::FrameRate_30_DROP: - return 30.0; - - case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME: - case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME: - return 29.9700262; - - case FileGlobalSettings::FrameRate_PAL: - return 25.0; - - case FileGlobalSettings::FrameRate_CINEMA: - return 24.0; - - case FileGlobalSettings::FrameRate_1000: - return 1000.0; - - case FileGlobalSettings::FrameRate_CINEMA_ND: - return 23.976; - - case FileGlobalSettings::FrameRate_CUSTOM: - return customFPSVal; - - case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings - break; - } - - ai_assert(false); - - return -1.0f; - } - - - void FBXConverter::ConvertAnimations() - { - // first of all determine framerate - const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode(); - const float custom = doc.GlobalSettings().CustomFrameRate(); - anim_fps = FrameRateToDouble(fps, custom); - - const std::vector<const AnimationStack*>& animations = doc.AnimationStacks(); - for (const AnimationStack* stack : animations) { - ConvertAnimationStack(*stack); - } - } - - std::string FBXConverter::FixNodeName(const std::string& name) { - // strip Model:: prefix, avoiding ambiguities (i.e. don't strip if - // this causes ambiguities, well possible between empty identifiers, - // such as "Model::" and ""). Make sure the behaviour is consistent - // across multiple calls to FixNodeName(). - if (name.substr(0, 7) == "Model::") { - std::string temp = name.substr(7); - return temp; - } - - return name; - } - - std::string FBXConverter::FixAnimMeshName(const std::string& name) { - if (name.length()) { - size_t indexOf = name.find_first_of("::"); - if (indexOf != std::string::npos && indexOf < name.size() - 2) { - return name.substr(indexOf + 2); - } - } - return name.length() ? name : "AnimMesh"; - } - - void FBXConverter::ConvertAnimationStack(const AnimationStack& st) - { - const AnimationLayerList& layers = st.Layers(); - if (layers.empty()) { - return; - } - - aiAnimation* const anim = new aiAnimation(); - animations.push_back(anim); - - // strip AnimationStack:: prefix - std::string name = st.Name(); - if (name.substr(0, 16) == "AnimationStack::") { - name = name.substr(16); - } - else if (name.substr(0, 11) == "AnimStack::") { - name = name.substr(11); - } - - anim->mName.Set(name); - - // need to find all nodes for which we need to generate node animations - - // it may happen that we need to merge multiple layers, though. - NodeMap node_map; - - // reverse mapping from curves to layers, much faster than querying - // the FBX DOM for it. - LayerMap layer_map; - - const char* prop_whitelist[] = { - "Lcl Scaling", - "Lcl Rotation", - "Lcl Translation", - "DeformPercent" - }; - - std::map<std::string, morphAnimData*> morphAnimDatas; - - for (const AnimationLayer* layer : layers) { - ai_assert(layer); - const AnimationCurveNodeList& nodes = layer->Nodes(prop_whitelist, 4); - for (const AnimationCurveNode* node : nodes) { - ai_assert(node); - const Model* const model = dynamic_cast<const Model*>(node->Target()); - if (model) { - const std::string& name = FixNodeName(model->Name()); - node_map[name].push_back(node); - layer_map[node] = layer; - continue; - } - const BlendShapeChannel* const bsc = dynamic_cast<const BlendShapeChannel*>(node->Target()); - if (bsc) { - ProcessMorphAnimDatas(&morphAnimDatas, bsc, node); - } - } - } - - // generate node animations - std::vector<aiNodeAnim*> node_anims; - - double min_time = 1e10; - double max_time = -1e10; - - int64_t start_time = st.LocalStart(); - int64_t stop_time = st.LocalStop(); - bool has_local_startstop = start_time != 0 || stop_time != 0; - if (!has_local_startstop) { - // no time range given, so accept every keyframe and use the actual min/max time - // the numbers are INT64_MIN/MAX, the 20000 is for safety because GenerateNodeAnimations uses an epsilon of 10000 - start_time = -9223372036854775807ll + 20000; - stop_time = 9223372036854775807ll - 20000; - } - - try { - for (const NodeMap::value_type& kv : node_map) { - GenerateNodeAnimations(node_anims, - kv.first, - kv.second, - layer_map, - start_time, stop_time, - max_time, - min_time); - } - } - catch (std::exception&) { - std::for_each(node_anims.begin(), node_anims.end(), Util::delete_fun<aiNodeAnim>()); - throw; - } - - if (node_anims.size() || morphAnimDatas.size()) { - if (node_anims.size()) { - anim->mChannels = new aiNodeAnim*[node_anims.size()](); - anim->mNumChannels = static_cast<unsigned int>(node_anims.size()); - std::swap_ranges(node_anims.begin(), node_anims.end(), anim->mChannels); - } - if (morphAnimDatas.size()) { - unsigned int numMorphMeshChannels = static_cast<unsigned int>(morphAnimDatas.size()); - anim->mMorphMeshChannels = new aiMeshMorphAnim*[numMorphMeshChannels]; - anim->mNumMorphMeshChannels = numMorphMeshChannels; - unsigned int i = 0; - for (auto morphAnimIt : morphAnimDatas) { - morphAnimData* animData = morphAnimIt.second; - unsigned int numKeys = static_cast<unsigned int>(animData->size()); - aiMeshMorphAnim* meshMorphAnim = new aiMeshMorphAnim(); - meshMorphAnim->mName.Set(morphAnimIt.first); - meshMorphAnim->mNumKeys = numKeys; - meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys]; - unsigned int j = 0; - for (auto animIt : *animData) { - morphKeyData* keyData = animIt.second; - unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size()); - meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights; - meshMorphAnim->mKeys[j].mValues = new unsigned int[numValuesAndWeights]; - meshMorphAnim->mKeys[j].mWeights = new double[numValuesAndWeights]; - meshMorphAnim->mKeys[j].mTime = CONVERT_FBX_TIME(animIt.first) * anim_fps; - for (unsigned int k = 0; k < numValuesAndWeights; k++) { - meshMorphAnim->mKeys[j].mValues[k] = keyData->values.at(k); - meshMorphAnim->mKeys[j].mWeights[k] = keyData->weights.at(k); - } - j++; - } - anim->mMorphMeshChannels[i++] = meshMorphAnim; - } - } - } - else { - // empty animations would fail validation, so drop them - delete anim; - animations.pop_back(); - FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): " + name); - return; - } - - double start_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(start_time) * anim_fps) : min_time; - double stop_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(stop_time) * anim_fps) : max_time; - - // adjust relative timing for animation - for (unsigned int c = 0; c < anim->mNumChannels; c++) { - aiNodeAnim* channel = anim->mChannels[c]; - for (uint32_t i = 0; i < channel->mNumPositionKeys; i++) { - channel->mPositionKeys[i].mTime -= start_time_fps; - } - for (uint32_t i = 0; i < channel->mNumRotationKeys; i++) { - channel->mRotationKeys[i].mTime -= start_time_fps; - } - for (uint32_t i = 0; i < channel->mNumScalingKeys; i++) { - channel->mScalingKeys[i].mTime -= start_time_fps; - } - } - for (unsigned int c = 0; c < anim->mNumMorphMeshChannels; c++) { - aiMeshMorphAnim* channel = anim->mMorphMeshChannels[c]; - for (uint32_t i = 0; i < channel->mNumKeys; i++) { - channel->mKeys[i].mTime -= start_time_fps; - } - } - - // for some mysterious reason, mDuration is simply the maximum key -- the - // validator always assumes animations to start at zero. - anim->mDuration = stop_time_fps - start_time_fps; - anim->mTicksPerSecond = anim_fps; - } - - // ------------------------------------------------------------------------------------------------ - void FBXConverter::ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas, const BlendShapeChannel* bsc, const AnimationCurveNode* node) { - std::vector<const Connection*> bscConnections = doc.GetConnectionsBySourceSequenced(bsc->ID(), "Deformer"); - for (const Connection* bscConnection : bscConnections) { - auto bs = dynamic_cast<const BlendShape*>(bscConnection->DestinationObject()); - if (bs) { - auto channelIt = std::find(bs->BlendShapeChannels().begin(), bs->BlendShapeChannels().end(), bsc); - if (channelIt != bs->BlendShapeChannels().end()) { - auto channelIndex = static_cast<unsigned int>(std::distance(bs->BlendShapeChannels().begin(), channelIt)); - std::vector<const Connection*> bsConnections = doc.GetConnectionsBySourceSequenced(bs->ID(), "Geometry"); - for (const Connection* bsConnection : bsConnections) { - auto geo = dynamic_cast<const Geometry*>(bsConnection->DestinationObject()); - if (geo) { - std::vector<const Connection*> geoConnections = doc.GetConnectionsBySourceSequenced(geo->ID(), "Model"); - for (const Connection* geoConnection : geoConnections) { - auto model = dynamic_cast<const Model*>(geoConnection->DestinationObject()); - if (model) { - auto geoIt = std::find(model->GetGeometry().begin(), model->GetGeometry().end(), geo); - auto geoIndex = static_cast<unsigned int>(std::distance(model->GetGeometry().begin(), geoIt)); - auto name = aiString(FixNodeName(model->Name() + "*")); - name.length = 1 + ASSIMP_itoa10(name.data + name.length, MAXLEN - 1, geoIndex); - morphAnimData* animData; - auto animIt = morphAnimDatas->find(name.C_Str()); - if (animIt == morphAnimDatas->end()) { - animData = new morphAnimData(); - morphAnimDatas->insert(std::make_pair(name.C_Str(), animData)); - } - else { - animData = animIt->second; - } - for (std::pair<std::string, const AnimationCurve*> curvesIt : node->Curves()) { - if (curvesIt.first == "d|DeformPercent") { - const AnimationCurve* animationCurve = curvesIt.second; - const KeyTimeList& keys = animationCurve->GetKeys(); - const KeyValueList& values = animationCurve->GetValues(); - unsigned int k = 0; - for (auto key : keys) { - morphKeyData* keyData; - auto keyIt = animData->find(key); - if (keyIt == animData->end()) { - keyData = new morphKeyData(); - animData->insert(std::make_pair(key, keyData)); - } - else { - keyData = keyIt->second; - } - keyData->values.push_back(channelIndex); - keyData->weights.push_back(values.at(k) / 100.0f); - k++; - } - } - } - } - } - } - } - } - } - } - } - - // ------------------------------------------------------------------------------------------------ -#ifdef ASSIMP_BUILD_DEBUG - // ------------------------------------------------------------------------------------------------ - // sanity check whether the input is ok - static void validateAnimCurveNodes(const std::vector<const AnimationCurveNode*>& curves, - bool strictMode) { - const Object* target(nullptr); - for (const AnimationCurveNode* node : curves) { - if (!target) { - target = node->Target(); - } - if (node->Target() != target) { - FBXImporter::LogWarn("Node target is nullptr type."); - } - if (strictMode) { - ai_assert(node->Target() == target); - } - } - } -#endif // ASSIMP_BUILD_DEBUG - - // ------------------------------------------------------------------------------------------------ - void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims, - const std::string& fixed_name, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time) - { - - NodeMap node_property_map; - ai_assert(curves.size()); - -#ifdef ASSIMP_BUILD_DEBUG - validateAnimCurveNodes(curves, doc.Settings().strictMode); -#endif - const AnimationCurveNode* curve_node = nullptr; - for (const AnimationCurveNode* node : curves) { - ai_assert(node); - - if (node->TargetProperty().empty()) { - FBXImporter::LogWarn("target property for animation curve not set: " + node->Name()); - continue; - } - - curve_node = node; - if (node->Curves().empty()) { - FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: " + node->Name()); - continue; - } - - node_property_map[node->TargetProperty()].push_back(node); - } - - ai_assert(curve_node); - ai_assert(curve_node->TargetAsModel()); - - const Model& target = *curve_node->TargetAsModel(); - - // check for all possible transformation components - NodeMap::const_iterator chain[TransformationComp_MAXIMUM]; - - bool has_any = false; - bool has_complex = false; - - for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) { - const TransformationComp comp = static_cast<TransformationComp>(i); - - // inverse pivots don't exist in the input, we just generate them - if (comp == TransformationComp_RotationPivotInverse || comp == TransformationComp_ScalingPivotInverse) { - chain[i] = node_property_map.end(); - continue; - } - - chain[i] = node_property_map.find(NameTransformationCompProperty(comp)); - if (chain[i] != node_property_map.end()) { - - // check if this curves contains redundant information by looking - // up the corresponding node's transformation chain. - if (doc.Settings().optimizeEmptyAnimationCurves && - IsRedundantAnimationData(target, comp, (*chain[i]).second)) { - - FBXImporter::LogDebug("dropping redundant animation channel for node " + target.Name()); - continue; - } - - has_any = true; - - if (comp != TransformationComp_Rotation && comp != TransformationComp_Scaling && comp != TransformationComp_Translation) - { - has_complex = true; - } - } - } - - if (!has_any) { - FBXImporter::LogWarn("ignoring node animation, did not find any transformation key frames"); - return; - } - - // this needs to play nicely with GenerateTransformationNodeChain() which will - // be invoked _later_ (animations come first). If this node has only rotation, - // scaling and translation _and_ there are no animated other components either, - // we can use a single node and also a single node animation channel. - if (!has_complex && !NeedsComplexTransformationChain(target)) { - - aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain, - node_property_map.end(), - layer_map, - start, stop, - max_time, - min_time, - true // input is TRS order, assimp is SRT - ); - - ai_assert(nd); - if (nd->mNumPositionKeys == 0 && nd->mNumRotationKeys == 0 && nd->mNumScalingKeys == 0) { - delete nd; - } - else { - node_anims.push_back(nd); - } - return; - } - - // otherwise, things get gruesome and we need separate animation channels - // for each part of the transformation chain. Remember which channels - // we generated and pass this information to the node conversion - // code to avoid nodes that have identity transform, but non-identity - // animations, being dropped. - unsigned int flags = 0, bit = 0x1; - for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) { - const TransformationComp comp = static_cast<TransformationComp>(i); - - if (chain[i] != node_property_map.end()) { - flags |= bit; - - ai_assert(comp != TransformationComp_RotationPivotInverse); - ai_assert(comp != TransformationComp_ScalingPivotInverse); - - const std::string& chain_name = NameTransformationChainNode(fixed_name, comp); - - aiNodeAnim* na = nullptr; - switch (comp) - { - case TransformationComp_Rotation: - case TransformationComp_PreRotation: - case TransformationComp_PostRotation: - case TransformationComp_GeometricRotation: - na = GenerateRotationNodeAnim(chain_name, - target, - (*chain[i]).second, - layer_map, - start, stop, - max_time, - min_time); - - break; - - case TransformationComp_RotationOffset: - case TransformationComp_RotationPivot: - case TransformationComp_ScalingOffset: - case TransformationComp_ScalingPivot: - case TransformationComp_Translation: - case TransformationComp_GeometricTranslation: - na = GenerateTranslationNodeAnim(chain_name, - target, - (*chain[i]).second, - layer_map, - start, stop, - max_time, - min_time); - - // pivoting requires us to generate an implicit inverse channel to undo the pivot translation - if (comp == TransformationComp_RotationPivot) { - const std::string& invName = NameTransformationChainNode(fixed_name, - TransformationComp_RotationPivotInverse); - - aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, - target, - (*chain[i]).second, - layer_map, - start, stop, - max_time, - min_time, - true); - - ai_assert(inv); - if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) { - delete inv; - } - else { - node_anims.push_back(inv); - } - - ai_assert(TransformationComp_RotationPivotInverse > i); - flags |= bit << (TransformationComp_RotationPivotInverse - i); - } - else if (comp == TransformationComp_ScalingPivot) { - const std::string& invName = NameTransformationChainNode(fixed_name, - TransformationComp_ScalingPivotInverse); - - aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, - target, - (*chain[i]).second, - layer_map, - start, stop, - max_time, - min_time, - true); - - ai_assert(inv); - if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) { - delete inv; - } - else { - node_anims.push_back(inv); - } - - ai_assert(TransformationComp_RotationPivotInverse > i); - flags |= bit << (TransformationComp_RotationPivotInverse - i); - } - - break; - - case TransformationComp_Scaling: - case TransformationComp_GeometricScaling: - na = GenerateScalingNodeAnim(chain_name, - target, - (*chain[i]).second, - layer_map, - start, stop, - max_time, - min_time); - - break; - - default: - ai_assert(false); - } - - ai_assert(na); - if (na->mNumPositionKeys == 0 && na->mNumRotationKeys == 0 && na->mNumScalingKeys == 0) { - delete na; - } - else { - node_anims.push_back(na); - } - continue; - } - } - - node_anim_chain_bits[fixed_name] = flags; - } - - - bool FBXConverter::IsRedundantAnimationData(const Model& target, - TransformationComp comp, - const std::vector<const AnimationCurveNode*>& curves) { - ai_assert(curves.size()); - - // look for animation nodes with - // * sub channels for all relevant components set - // * one key/value pair per component - // * combined values match up the corresponding value in the bind pose node transformation - // only such nodes are 'redundant' for this function. - - if (curves.size() > 1) { - return false; - } - - const AnimationCurveNode& nd = *curves.front(); - const AnimationCurveMap& sub_curves = nd.Curves(); - - const AnimationCurveMap::const_iterator dx = sub_curves.find("d|X"); - const AnimationCurveMap::const_iterator dy = sub_curves.find("d|Y"); - const AnimationCurveMap::const_iterator dz = sub_curves.find("d|Z"); - - if (dx == sub_curves.end() || dy == sub_curves.end() || dz == sub_curves.end()) { - return false; - } - - const KeyValueList& vx = (*dx).second->GetValues(); - const KeyValueList& vy = (*dy).second->GetValues(); - const KeyValueList& vz = (*dz).second->GetValues(); - - if (vx.size() != 1 || vy.size() != 1 || vz.size() != 1) { - return false; - } - - const aiVector3D dyn_val = aiVector3D(vx[0], vy[0], vz[0]); - const aiVector3D& static_val = PropertyGet<aiVector3D>(target.Props(), - NameTransformationCompProperty(comp), - TransformationCompDefaultValue(comp) - ); - - const float epsilon = Math::getEpsilon<float>(); - return (dyn_val - static_val).SquareLength() < epsilon; - } - - - aiNodeAnim* FBXConverter::GenerateRotationNodeAnim(const std::string& name, - const Model& target, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time) - { - std::unique_ptr<aiNodeAnim> na(new aiNodeAnim()); - na->mNodeName.Set(name); - - ConvertRotationKeys(na.get(), curves, layer_map, start, stop, max_time, min_time, target.RotationOrder()); - - // dummy scaling key - na->mScalingKeys = new aiVectorKey[1]; - na->mNumScalingKeys = 1; - - na->mScalingKeys[0].mTime = 0.; - na->mScalingKeys[0].mValue = aiVector3D(1.0f, 1.0f, 1.0f); - - // dummy position key - na->mPositionKeys = new aiVectorKey[1]; - na->mNumPositionKeys = 1; - - na->mPositionKeys[0].mTime = 0.; - na->mPositionKeys[0].mValue = aiVector3D(); - - return na.release(); - } - - aiNodeAnim* FBXConverter::GenerateScalingNodeAnim(const std::string& name, - const Model& /*target*/, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time) - { - std::unique_ptr<aiNodeAnim> na(new aiNodeAnim()); - na->mNodeName.Set(name); - - ConvertScaleKeys(na.get(), curves, layer_map, start, stop, max_time, min_time); - - // dummy rotation key - na->mRotationKeys = new aiQuatKey[1]; - na->mNumRotationKeys = 1; - - na->mRotationKeys[0].mTime = 0.; - na->mRotationKeys[0].mValue = aiQuaternion(); - - // dummy position key - na->mPositionKeys = new aiVectorKey[1]; - na->mNumPositionKeys = 1; - - na->mPositionKeys[0].mTime = 0.; - na->mPositionKeys[0].mValue = aiVector3D(); - - return na.release(); - } - - aiNodeAnim* FBXConverter::GenerateTranslationNodeAnim(const std::string& name, - const Model& /*target*/, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time, - bool inverse) { - std::unique_ptr<aiNodeAnim> na(new aiNodeAnim()); - na->mNodeName.Set(name); - - ConvertTranslationKeys(na.get(), curves, layer_map, start, stop, max_time, min_time); - - if (inverse) { - for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) { - na->mPositionKeys[i].mValue *= -1.0f; - } - } - - // dummy scaling key - na->mScalingKeys = new aiVectorKey[1]; - na->mNumScalingKeys = 1; - - na->mScalingKeys[0].mTime = 0.; - na->mScalingKeys[0].mValue = aiVector3D(1.0f, 1.0f, 1.0f); - - // dummy rotation key - na->mRotationKeys = new aiQuatKey[1]; - na->mNumRotationKeys = 1; - - na->mRotationKeys[0].mTime = 0.; - na->mRotationKeys[0].mValue = aiQuaternion(); - - return na.release(); - } - - aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name, - const Model& target, - NodeMap::const_iterator chain[TransformationComp_MAXIMUM], - NodeMap::const_iterator iter_end, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time, - bool reverse_order) - - { - std::unique_ptr<aiNodeAnim> na(new aiNodeAnim()); - na->mNodeName.Set(name); - - const PropertyTable& props = target.Props(); - - // need to convert from TRS order to SRT? - if (reverse_order) { - - aiVector3D def_scale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f)); - aiVector3D def_translate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f)); - aiVector3D def_rot = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f)); - - KeyFrameListList scaling; - KeyFrameListList translation; - KeyFrameListList rotation; - - if (chain[TransformationComp_Scaling] != iter_end) { - scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop); - } - - if (chain[TransformationComp_Translation] != iter_end) { - translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop); - } - - if (chain[TransformationComp_Rotation] != iter_end) { - rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop); - } - - KeyFrameListList joined; - joined.insert(joined.end(), scaling.begin(), scaling.end()); - joined.insert(joined.end(), translation.begin(), translation.end()); - joined.insert(joined.end(), rotation.begin(), rotation.end()); - - const KeyTimeList& times = GetKeyTimeList(joined); - - aiQuatKey* out_quat = new aiQuatKey[times.size()]; - aiVectorKey* out_scale = new aiVectorKey[times.size()]; - aiVectorKey* out_translation = new aiVectorKey[times.size()]; - - if (times.size()) - { - ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation, - scaling, - translation, - rotation, - times, - max_time, - min_time, - target.RotationOrder(), - def_scale, - def_translate, - def_rot); - } - - // XXX remove duplicates / redundant keys which this operation did - // likely produce if not all three channels were equally dense. - - na->mNumScalingKeys = static_cast<unsigned int>(times.size()); - na->mNumRotationKeys = na->mNumScalingKeys; - na->mNumPositionKeys = na->mNumScalingKeys; - - na->mScalingKeys = out_scale; - na->mRotationKeys = out_quat; - na->mPositionKeys = out_translation; - } - else { - - // if a particular transformation is not given, grab it from - // the corresponding node to meet the semantics of aiNodeAnim, - // which requires all of rotation, scaling and translation - // to be set. - if (chain[TransformationComp_Scaling] != iter_end) { - ConvertScaleKeys(na.get(), (*chain[TransformationComp_Scaling]).second, - layer_map, - start, stop, - max_time, - min_time); - } - else { - na->mScalingKeys = new aiVectorKey[1]; - na->mNumScalingKeys = 1; - - na->mScalingKeys[0].mTime = 0.; - na->mScalingKeys[0].mValue = PropertyGet(props, "Lcl Scaling", - aiVector3D(1.f, 1.f, 1.f)); - } - - if (chain[TransformationComp_Rotation] != iter_end) { - ConvertRotationKeys(na.get(), (*chain[TransformationComp_Rotation]).second, - layer_map, - start, stop, - max_time, - min_time, - target.RotationOrder()); - } - else { - na->mRotationKeys = new aiQuatKey[1]; - na->mNumRotationKeys = 1; - - na->mRotationKeys[0].mTime = 0.; - na->mRotationKeys[0].mValue = EulerToQuaternion( - PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f)), - target.RotationOrder()); - } - - if (chain[TransformationComp_Translation] != iter_end) { - ConvertTranslationKeys(na.get(), (*chain[TransformationComp_Translation]).second, - layer_map, - start, stop, - max_time, - min_time); - } - else { - na->mPositionKeys = new aiVectorKey[1]; - na->mNumPositionKeys = 1; - - na->mPositionKeys[0].mTime = 0.; - na->mPositionKeys[0].mValue = PropertyGet(props, "Lcl Translation", - aiVector3D(0.f, 0.f, 0.f)); - } - - } - return na.release(); - } - - FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop) - { - KeyFrameListList inputs; - inputs.reserve(nodes.size() * 3); - - //give some breathing room for rounding errors - int64_t adj_start = start - 10000; - int64_t adj_stop = stop + 10000; - - for (const AnimationCurveNode* node : nodes) { - ai_assert(node); - - const AnimationCurveMap& curves = node->Curves(); - for (const AnimationCurveMap::value_type& kv : curves) { - - unsigned int mapto; - if (kv.first == "d|X") { - mapto = 0; - } - else if (kv.first == "d|Y") { - mapto = 1; - } - else if (kv.first == "d|Z") { - mapto = 2; - } - else { - FBXImporter::LogWarn("ignoring scale animation curve, did not recognize target component"); - continue; - } - - const AnimationCurve* const curve = kv.second; - ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size()); - - //get values within the start/stop time window - std::shared_ptr<KeyTimeList> Keys(new KeyTimeList()); - std::shared_ptr<KeyValueList> Values(new KeyValueList()); - const size_t count = curve->GetKeys().size(); - Keys->reserve(count); - Values->reserve(count); - for (size_t n = 0; n < count; n++) - { - int64_t k = curve->GetKeys().at(n); - if (k >= adj_start && k <= adj_stop) - { - Keys->push_back(k); - Values->push_back(curve->GetValues().at(n)); - } - } - - inputs.push_back(std::make_tuple(Keys, Values, mapto)); - } - } - return inputs; // pray for NRVO :-) - } - - - KeyTimeList FBXConverter::GetKeyTimeList(const KeyFrameListList& inputs) { - ai_assert(!inputs.empty()); - - // reserve some space upfront - it is likely that the key-frame lists - // have matching time values, so max(of all key-frame lists) should - // be a good estimate. - KeyTimeList keys; - - size_t estimate = 0; - for (const KeyFrameList& kfl : inputs) { - estimate = std::max(estimate, std::get<0>(kfl)->size()); - } - - keys.reserve(estimate); - - std::vector<unsigned int> next_pos; - next_pos.resize(inputs.size(), 0); - - const size_t count = inputs.size(); - while (true) { - - int64_t min_tick = std::numeric_limits<int64_t>::max(); - for (size_t i = 0; i < count; ++i) { - const KeyFrameList& kfl = inputs[i]; - - if (std::get<0>(kfl)->size() > next_pos[i] && std::get<0>(kfl)->at(next_pos[i]) < min_tick) { - min_tick = std::get<0>(kfl)->at(next_pos[i]); - } - } - - if (min_tick == std::numeric_limits<int64_t>::max()) { - break; - } - keys.push_back(min_tick); - - for (size_t i = 0; i < count; ++i) { - const KeyFrameList& kfl = inputs[i]; - - - while (std::get<0>(kfl)->size() > next_pos[i] && std::get<0>(kfl)->at(next_pos[i]) == min_tick) { - ++next_pos[i]; - } - } - } - - return keys; - } - - void FBXConverter::InterpolateKeys(aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, - const aiVector3D& def_value, - double& max_time, - double& min_time) { - ai_assert(!keys.empty()); - ai_assert(nullptr != valOut); - - std::vector<unsigned int> next_pos; - const size_t count(inputs.size()); - - next_pos.resize(inputs.size(), 0); - - for (KeyTimeList::value_type time : keys) { - ai_real result[3] = { def_value.x, def_value.y, def_value.z }; - - for (size_t i = 0; i < count; ++i) { - const KeyFrameList& kfl = inputs[i]; - - const size_t ksize = std::get<0>(kfl)->size(); - if (ksize == 0) { - continue; - } - if (ksize > next_pos[i] && std::get<0>(kfl)->at(next_pos[i]) == time) { - ++next_pos[i]; - } - - const size_t id0 = next_pos[i] > 0 ? next_pos[i] - 1 : 0; - const size_t id1 = next_pos[i] == ksize ? ksize - 1 : next_pos[i]; - - // use lerp for interpolation - const KeyValueList::value_type valueA = std::get<1>(kfl)->at(id0); - const KeyValueList::value_type valueB = std::get<1>(kfl)->at(id1); - - const KeyTimeList::value_type timeA = std::get<0>(kfl)->at(id0); - const KeyTimeList::value_type timeB = std::get<0>(kfl)->at(id1); - - const ai_real factor = timeB == timeA ? ai_real(0.) : static_cast<ai_real>((time - timeA)) / (timeB - timeA); - const ai_real interpValue = static_cast<ai_real>(valueA + (valueB - valueA) * factor); - - result[std::get<2>(kfl)] = interpValue; - } - - // magic value to convert fbx times to seconds - valOut->mTime = CONVERT_FBX_TIME(time) * anim_fps; - - min_time = std::min(min_time, valOut->mTime); - max_time = std::max(max_time, valOut->mTime); - - valOut->mValue.x = result[0]; - valOut->mValue.y = result[1]; - valOut->mValue.z = result[2]; - - ++valOut; - } - } - - void FBXConverter::InterpolateKeys(aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, - const aiVector3D& def_value, - double& maxTime, - double& minTime, - Model::RotOrder order) - { - ai_assert(!keys.empty()); - ai_assert(nullptr != valOut); - - std::unique_ptr<aiVectorKey[]> temp(new aiVectorKey[keys.size()]); - InterpolateKeys(temp.get(), keys, inputs, def_value, maxTime, minTime); - - aiMatrix4x4 m; - - aiQuaternion lastq; - - for (size_t i = 0, c = keys.size(); i < c; ++i) { - - valOut[i].mTime = temp[i].mTime; - - GetRotationMatrix(order, temp[i].mValue, m); - aiQuaternion quat = aiQuaternion(aiMatrix3x3(m)); - - // take shortest path by checking the inner product - // http://www.3dkingdoms.com/weekly/weekly.php?a=36 - if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) - { - quat.x = -quat.x; - quat.y = -quat.y; - quat.z = -quat.z; - quat.w = -quat.w; - } - lastq = quat; - - valOut[i].mValue = quat; - } - } - - void FBXConverter::ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale, - aiVectorKey* out_translation, - const KeyFrameListList& scaling, - const KeyFrameListList& translation, - const KeyFrameListList& rotation, - const KeyTimeList& times, - double& maxTime, - double& minTime, - Model::RotOrder order, - const aiVector3D& def_scale, - const aiVector3D& def_translate, - const aiVector3D& def_rotation) - { - if (rotation.size()) { - InterpolateKeys(out_quat, times, rotation, def_rotation, maxTime, minTime, order); - } - else { - for (size_t i = 0; i < times.size(); ++i) { - out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps; - out_quat[i].mValue = EulerToQuaternion(def_rotation, order); - } - } - - if (scaling.size()) { - InterpolateKeys(out_scale, times, scaling, def_scale, maxTime, minTime); - } - else { - for (size_t i = 0; i < times.size(); ++i) { - out_scale[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps; - out_scale[i].mValue = def_scale; - } - } - - if (translation.size()) { - InterpolateKeys(out_translation, times, translation, def_translate, maxTime, minTime); - } - else { - for (size_t i = 0; i < times.size(); ++i) { - out_translation[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps; - out_translation[i].mValue = def_translate; - } - } - - const size_t count = times.size(); - for (size_t i = 0; i < count; ++i) { - aiQuaternion& r = out_quat[i].mValue; - aiVector3D& s = out_scale[i].mValue; - aiVector3D& t = out_translation[i].mValue; - - aiMatrix4x4 mat, temp; - aiMatrix4x4::Translation(t, mat); - mat *= aiMatrix4x4(r.GetMatrix()); - mat *= aiMatrix4x4::Scaling(s, temp); - - mat.Decompose(s, r, t); - } - } - - aiQuaternion FBXConverter::EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order) - { - aiMatrix4x4 m; - GetRotationMatrix(order, rot, m); - - return aiQuaternion(aiMatrix3x3(m)); - } - - void FBXConverter::ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/, - int64_t start, int64_t stop, - double& maxTime, - double& minTime) - { - ai_assert(nodes.size()); - - // XXX for now, assume scale should be blended geometrically (i.e. two - // layers should be multiplied with each other). There is a FBX - // property in the layer to specify the behaviour, though. - - const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop); - const KeyTimeList& keys = GetKeyTimeList(inputs); - - na->mNumScalingKeys = static_cast<unsigned int>(keys.size()); - na->mScalingKeys = new aiVectorKey[keys.size()]; - if (keys.size() > 0) { - InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime); - } - } - - void FBXConverter::ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, - const LayerMap& /*layers*/, - int64_t start, int64_t stop, - double& maxTime, - double& minTime) - { - ai_assert(nodes.size()); - - // XXX see notes in ConvertScaleKeys() - const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop); - const KeyTimeList& keys = GetKeyTimeList(inputs); - - na->mNumPositionKeys = static_cast<unsigned int>(keys.size()); - na->mPositionKeys = new aiVectorKey[keys.size()]; - if (keys.size() > 0) - InterpolateKeys(na->mPositionKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime); - } - - void FBXConverter::ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, - const LayerMap& /*layers*/, - int64_t start, int64_t stop, - double& maxTime, - double& minTime, - Model::RotOrder order) - { - ai_assert(nodes.size()); - - // XXX see notes in ConvertScaleKeys() - const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes, start, stop); - const KeyTimeList& keys = GetKeyTimeList(inputs); - - na->mNumRotationKeys = static_cast<unsigned int>(keys.size()); - na->mRotationKeys = new aiQuatKey[keys.size()]; - if (!keys.empty()) { - InterpolateKeys(na->mRotationKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime, order); - } - } - - void FBXConverter::ConvertGlobalSettings() { - if (nullptr == out) { - return; - } - - out->mMetaData = aiMetadata::Alloc(15); - out->mMetaData->Set(0, "UpAxis", doc.GlobalSettings().UpAxis()); - out->mMetaData->Set(1, "UpAxisSign", doc.GlobalSettings().UpAxisSign()); - out->mMetaData->Set(2, "FrontAxis", doc.GlobalSettings().FrontAxis()); - out->mMetaData->Set(3, "FrontAxisSign", doc.GlobalSettings().FrontAxisSign()); - out->mMetaData->Set(4, "CoordAxis", doc.GlobalSettings().CoordAxis()); - out->mMetaData->Set(5, "CoordAxisSign", doc.GlobalSettings().CoordAxisSign()); - out->mMetaData->Set(6, "OriginalUpAxis", doc.GlobalSettings().OriginalUpAxis()); - out->mMetaData->Set(7, "OriginalUpAxisSign", doc.GlobalSettings().OriginalUpAxisSign()); - out->mMetaData->Set(8, "UnitScaleFactor", (double)doc.GlobalSettings().UnitScaleFactor()); - out->mMetaData->Set(9, "OriginalUnitScaleFactor", doc.GlobalSettings().OriginalUnitScaleFactor()); - out->mMetaData->Set(10, "AmbientColor", doc.GlobalSettings().AmbientColor()); - out->mMetaData->Set(11, "FrameRate", (int)doc.GlobalSettings().TimeMode()); - out->mMetaData->Set(12, "TimeSpanStart", doc.GlobalSettings().TimeSpanStart()); - out->mMetaData->Set(13, "TimeSpanStop", doc.GlobalSettings().TimeSpanStop()); - out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate()); - } - - void FBXConverter::TransferDataToScene() - { - ai_assert(!out->mMeshes); - ai_assert(!out->mNumMeshes); - - // note: the trailing () ensures initialization with nullptr - not - // many C++ users seem to know this, so pointing it out to avoid - // confusion why this code works. - - if (meshes.size()) { - out->mMeshes = new aiMesh*[meshes.size()](); - out->mNumMeshes = static_cast<unsigned int>(meshes.size()); - - std::swap_ranges(meshes.begin(), meshes.end(), out->mMeshes); - } - - if (materials.size()) { - out->mMaterials = new aiMaterial*[materials.size()](); - out->mNumMaterials = static_cast<unsigned int>(materials.size()); - - std::swap_ranges(materials.begin(), materials.end(), out->mMaterials); - } - - if (animations.size()) { - out->mAnimations = new aiAnimation*[animations.size()](); - out->mNumAnimations = static_cast<unsigned int>(animations.size()); - - std::swap_ranges(animations.begin(), animations.end(), out->mAnimations); - } - - if (lights.size()) { - out->mLights = new aiLight*[lights.size()](); - out->mNumLights = static_cast<unsigned int>(lights.size()); - - std::swap_ranges(lights.begin(), lights.end(), out->mLights); - } - - if (cameras.size()) { - out->mCameras = new aiCamera*[cameras.size()](); - out->mNumCameras = static_cast<unsigned int>(cameras.size()); - - std::swap_ranges(cameras.begin(), cameras.end(), out->mCameras); - } - - if (textures.size()) { - out->mTextures = new aiTexture*[textures.size()](); - out->mNumTextures = static_cast<unsigned int>(textures.size()); - - std::swap_ranges(textures.begin(), textures.end(), out->mTextures); - } - } - - void FBXConverter::ConvertOrphantEmbeddedTextures() - { - // in C++14 it could be: - // for (auto&& [id, object] : objects) - for (auto&& id_and_object : doc.Objects()) - { - auto&& id = std::get<0>(id_and_object); - auto&& object = std::get<1>(id_and_object); - // If an object doesn't have parent - if (doc.ConnectionsBySource().count(id) == 0) - { - const Texture* realTexture = nullptr; - try - { - const auto& element = object->GetElement(); - const Token& key = element.KeyToken(); - const char* obtype = key.begin(); - const size_t length = static_cast<size_t>(key.end() - key.begin()); - if (strncmp(obtype, "Texture", length) == 0) - { - const Texture* texture = static_cast<const Texture*>(object->Get()); - if (texture->Media() && texture->Media()->ContentLength() > 0) - { - realTexture = texture; - } - } - } - catch (...) - { - // do nothing - } - if (realTexture) - { - const Video* media = realTexture->Media(); - unsigned int index = ConvertVideo(*media); - textures_converted[*media] = index; - } - } - } - } - - // ------------------------------------------------------------------------------------------------ - void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones) - { - FBXConverter converter(out, doc, removeEmptyBones); - } - - } // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h deleted file mode 100644 index 46693bdca6..0000000000 --- a/thirdparty/assimp/code/FBX/FBXConverter.h +++ /dev/null @@ -1,491 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXDConverter.h - * @brief FBX DOM to aiScene conversion - */ -#ifndef INCLUDED_AI_FBX_CONVERTER_H -#define INCLUDED_AI_FBX_CONVERTER_H - -#include "FBXParser.h" -#include "FBXMeshGeometry.h" -#include "FBXDocument.h" -#include "FBXUtil.h" -#include "FBXProperties.h" -#include "FBXImporter.h" - -#include <assimp/anim.h> -#include <assimp/material.h> -#include <assimp/light.h> -#include <assimp/texture.h> -#include <assimp/camera.h> -#include <assimp/StringComparison.h> -#include <unordered_map> -#include <unordered_set> - -struct aiScene; -struct aiNode; -struct aiMaterial; - -struct morphKeyData { - std::vector<unsigned int> values; - std::vector<float> weights; -}; -typedef std::map<int64_t, morphKeyData*> morphAnimData; - -namespace Assimp { -namespace FBX { - -class Document; -/** - * Convert a FBX #Document to #aiScene - * @param out Empty scene to be populated - * @param doc Parsed FBX document - * @param removeEmptyBones Will remove bones, which do not have any references to vertices. - */ -void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones); - -/** Dummy class to encapsulate the conversion process */ -class FBXConverter { -public: - /** - * The different parts that make up the final local transformation of a fbx-node - */ - enum TransformationComp { - TransformationComp_GeometricScalingInverse = 0, - TransformationComp_GeometricRotationInverse, - TransformationComp_GeometricTranslationInverse, - TransformationComp_Translation, - TransformationComp_RotationOffset, - TransformationComp_RotationPivot, - TransformationComp_PreRotation, - TransformationComp_Rotation, - TransformationComp_PostRotation, - TransformationComp_RotationPivotInverse, - TransformationComp_ScalingOffset, - TransformationComp_ScalingPivot, - TransformationComp_Scaling, - TransformationComp_ScalingPivotInverse, - TransformationComp_GeometricTranslation, - TransformationComp_GeometricRotation, - TransformationComp_GeometricScaling, - - TransformationComp_MAXIMUM - }; - -public: - FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones); - ~FBXConverter(); - -private: - // ------------------------------------------------------------------------------------------------ - // find scene root and trigger recursive scene conversion - void ConvertRootNode(); - - // ------------------------------------------------------------------------------------------------ - // collect and assign child nodes - void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node); - - // ------------------------------------------------------------------------------------------------ - void ConvertLights(const Model& model, const std::string &orig_name ); - - // ------------------------------------------------------------------------------------------------ - void ConvertCameras(const Model& model, const std::string &orig_name ); - - // ------------------------------------------------------------------------------------------------ - void ConvertLight( const Light& light, const std::string &orig_name ); - - // ------------------------------------------------------------------------------------------------ - void ConvertCamera( const Camera& cam, const std::string &orig_name ); - - // ------------------------------------------------------------------------------------------------ - void GetUniqueName( const std::string &name, std::string& uniqueName ); - - // ------------------------------------------------------------------------------------------------ - // this returns unified names usable within assimp identifiers (i.e. no space characters - - // while these would be allowed, they are a potential trouble spot so better not use them). - const char* NameTransformationComp(TransformationComp comp); - - // ------------------------------------------------------------------------------------------------ - // Returns an unique name for a node or traverses up a hierarchy until a non-empty name is found and - // then makes this name unique - std::string MakeUniqueNodeName(const Model* const model, const aiNode& parent); - - // ------------------------------------------------------------------------------------------------ - // note: this returns the REAL fbx property names - const char* NameTransformationCompProperty(TransformationComp comp); - - // ------------------------------------------------------------------------------------------------ - aiVector3D TransformationCompDefaultValue(TransformationComp comp); - - // ------------------------------------------------------------------------------------------------ - void GetRotationMatrix(Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out); - // ------------------------------------------------------------------------------------------------ - /** - * checks if a node has more than just scaling, rotation and translation components - */ - bool NeedsComplexTransformationChain(const Model& model); - - // ------------------------------------------------------------------------------------------------ - // note: name must be a FixNodeName() result - std::string NameTransformationChainNode(const std::string& name, TransformationComp comp); - - // ------------------------------------------------------------------------------------------------ - /** - * note: memory for output_nodes will be managed by the caller - */ - bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes); - - // ------------------------------------------------------------------------------------------------ - void SetupNodeMetadata(const Model& model, aiNode& nd); - - // ------------------------------------------------------------------------------------------------ - void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, - const aiMatrix4x4 &absolute_transform); - - // ------------------------------------------------------------------------------------------------ - // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed - std::vector<unsigned int> - ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, - const aiMatrix4x4 &absolute_transform); - - // ------------------------------------------------------------------------------------------------ - std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model, - aiNode *parent, aiNode *root_node); - - // ------------------------------------------------------------------------------------------------ - aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent); - - // ------------------------------------------------------------------------------------------------ - unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, - const aiMatrix4x4 &absolute_transform, aiNode *parent, - aiNode *root_node); - - // ------------------------------------------------------------------------------------------------ - std::vector<unsigned int> - ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, - const aiMatrix4x4 &absolute_transform); - - // ------------------------------------------------------------------------------------------------ - unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index, - aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform); - - // ------------------------------------------------------------------------------------------------ - static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */ - static_cast<unsigned int>(-1); - - // ------------------------------------------------------------------------------------------------ - /** - * - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into - * account when determining which weights to include. - * - outputVertStartIndices is only used when a material index is specified, it gives for - * each output vertex the DOM index it maps to. - */ - void ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, - aiNode *parent = NULL, aiNode *root_node = NULL, - unsigned int materialIndex = NO_MATERIAL_SEPARATION, - std::vector<unsigned int> *outputVertStartIndices = NULL); - // lookup - static const aiNode* GetNodeByName( const aiString& name, aiNode *current_node ); - // ------------------------------------------------------------------------------------------------ - void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl, - std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices, - std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, - aiNode *parent, aiNode *root_node); - - // ------------------------------------------------------------------------------------------------ - void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo, - MatIndexArray::value_type materialIndex); - - // ------------------------------------------------------------------------------------------------ - unsigned int GetDefaultMaterial(); - - // ------------------------------------------------------------------------------------------------ - // Material -> aiMaterial - unsigned int ConvertMaterial(const Material& material, const MeshGeometry* const mesh); - - // ------------------------------------------------------------------------------------------------ - // Video -> aiTexture - unsigned int ConvertVideo(const Video& video); - - // ------------------------------------------------------------------------------------------------ - // convert embedded texture if necessary and return actual texture path - aiString GetTexturePath(const Texture* tex); - - // ------------------------------------------------------------------------------------------------ - void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, - const std::string& propName, - aiTextureType target, const MeshGeometry* const mesh); - - // ------------------------------------------------------------------------------------------------ - void TrySetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, - const std::string& propName, - aiTextureType target, const MeshGeometry* const mesh); - - // ------------------------------------------------------------------------------------------------ - void SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh); - - // ------------------------------------------------------------------------------------------------ - void SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh); - - // ------------------------------------------------------------------------------------------------ - aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props, const std::string& baseName, - bool& result); - aiColor3D GetColorPropertyFactored(const PropertyTable& props, const std::string& colorName, - const std::string& factorName, bool& result, bool useTemplate = true); - aiColor3D GetColorProperty(const PropertyTable& props, const std::string& colorName, - bool& result, bool useTemplate = true); - - // ------------------------------------------------------------------------------------------------ - void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props); - void SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTable& props, const TextureMap& textures, const MeshGeometry* const mesh); - - // ------------------------------------------------------------------------------------------------ - // get the number of fps for a FrameRate enumerated value - static double FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0); - - // ------------------------------------------------------------------------------------------------ - // convert animation data to aiAnimation et al - void ConvertAnimations(); - - // ------------------------------------------------------------------------------------------------ - // takes a fbx node name and returns the identifier to be used in the assimp output scene. - // the function is guaranteed to provide consistent results over multiple invocations - // UNLESS RenameNode() is called for a particular node name. - std::string FixNodeName(const std::string& name); - std::string FixAnimMeshName(const std::string& name); - - typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap; - - // XXX: better use multi_map .. - typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap; - - // ------------------------------------------------------------------------------------------------ - void ConvertAnimationStack(const AnimationStack& st); - - // ------------------------------------------------------------------------------------------------ - void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas, const BlendShapeChannel* bsc, const AnimationCurveNode* node); - - // ------------------------------------------------------------------------------------------------ - void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims, - const std::string& fixed_name, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time); - - // ------------------------------------------------------------------------------------------------ - bool IsRedundantAnimationData(const Model& target, - TransformationComp comp, - const std::vector<const AnimationCurveNode*>& curves); - - // ------------------------------------------------------------------------------------------------ - aiNodeAnim* GenerateRotationNodeAnim(const std::string& name, - const Model& target, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time); - - // ------------------------------------------------------------------------------------------------ - aiNodeAnim* GenerateScalingNodeAnim(const std::string& name, - const Model& /*target*/, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time); - - // ------------------------------------------------------------------------------------------------ - aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name, - const Model& /*target*/, - const std::vector<const AnimationCurveNode*>& curves, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time, - bool inverse = false); - - // ------------------------------------------------------------------------------------------------ - // generate node anim, extracting only Rotation, Scaling and Translation from the given chain - aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name, - const Model& target, - NodeMap::const_iterator chain[TransformationComp_MAXIMUM], - NodeMap::const_iterator iter_end, - const LayerMap& layer_map, - int64_t start, int64_t stop, - double& max_time, - double& min_time, - bool reverse_order = false); - - // key (time), value, mapto (component index) - typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList; - typedef std::vector<KeyFrameList> KeyFrameListList; - - // ------------------------------------------------------------------------------------------------ - KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop); - - // ------------------------------------------------------------------------------------------------ - KeyTimeList GetKeyTimeList(const KeyFrameListList& inputs); - - // ------------------------------------------------------------------------------------------------ - void InterpolateKeys(aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, - const aiVector3D& def_value, - double& max_time, - double& min_time); - - // ------------------------------------------------------------------------------------------------ - void InterpolateKeys(aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, - const aiVector3D& def_value, - double& maxTime, - double& minTime, - Model::RotOrder order); - - // ------------------------------------------------------------------------------------------------ - void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale, - aiVectorKey* out_translation, - const KeyFrameListList& scaling, - const KeyFrameListList& translation, - const KeyFrameListList& rotation, - const KeyTimeList& times, - double& maxTime, - double& minTime, - Model::RotOrder order, - const aiVector3D& def_scale, - const aiVector3D& def_translate, - const aiVector3D& def_rotation); - - // ------------------------------------------------------------------------------------------------ - // euler xyz -> quat - aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order); - - // ------------------------------------------------------------------------------------------------ - void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/, - int64_t start, int64_t stop, - double& maxTime, - double& minTime); - - // ------------------------------------------------------------------------------------------------ - void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, - const LayerMap& /*layers*/, - int64_t start, int64_t stop, - double& maxTime, - double& minTime); - - // ------------------------------------------------------------------------------------------------ - void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, - const LayerMap& /*layers*/, - int64_t start, int64_t stop, - double& maxTime, - double& minTime, - Model::RotOrder order); - - void ConvertGlobalSettings(); - - // ------------------------------------------------------------------------------------------------ - // copy generated meshes, animations, lights, cameras and textures to the output scene - void TransferDataToScene(); - - // ------------------------------------------------------------------------------------------------ - // FBX file could have embedded textures not connected to anything - void ConvertOrphantEmbeddedTextures(); - -private: - // 0: not assigned yet, others: index is value - 1 - unsigned int defaultMaterialIndex; - - std::vector<aiMesh*> meshes; - std::vector<aiMaterial*> materials; - std::vector<aiAnimation*> animations; - std::vector<aiLight*> lights; - std::vector<aiCamera*> cameras; - std::vector<aiTexture*> textures; - - using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>; - MaterialMap materials_converted; - - using VideoMap = std::fbx_unordered_map<const Video, unsigned int>; - VideoMap textures_converted; - - using MeshMap = std::fbx_unordered_map<const Geometry*, std::vector<unsigned int> >; - MeshMap meshes_converted; - - // fixed node name -> which trafo chain components have animations? - using NodeAnimBitMap = std::fbx_unordered_map<std::string, unsigned int> ; - NodeAnimBitMap node_anim_chain_bits; - - // number of nodes with the same name - using NodeNameCache = std::fbx_unordered_map<std::string, unsigned int>; - NodeNameCache mNodeNames; - - // Deformer name is not the same as a bone name - it does contain the bone name though :) - // Deformer names in FBX are always unique in an FBX file. - std::map<const std::string, aiBone *> bone_map; - - double anim_fps; - - aiScene* const out; - const FBX::Document& doc; - - static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene, - std::vector<aiBone*>& bones); - - void BuildBoneStack(aiNode *current_node, const aiNode *root_node, const aiScene *scene, - const std::vector<aiBone *> &bones, - std::map<aiBone *, aiNode *> &bone_stack, - std::vector<aiNode*> &node_stack ); - - static void BuildNodeList(aiNode *current_node, std::vector<aiNode *> &nodes); - - static aiNode *GetNodeFromStack(const aiString &node_name, std::vector<aiNode *> &nodes); - - static aiNode *GetArmatureRoot(aiNode *bone_node, std::vector<aiBone*> &bone_list); - - static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones); -}; - -} -} - -#endif // INCLUDED_AI_FBX_CONVERTER_H diff --git a/thirdparty/assimp/code/FBX/FBXDeformer.cpp b/thirdparty/assimp/code/FBX/FBXDeformer.cpp deleted file mode 100644 index 6927553450..0000000000 --- a/thirdparty/assimp/code/FBX/FBXDeformer.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXNoteAttribute.cpp - * @brief Assimp::FBX::NodeAttribute (and subclasses) implementation - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXParser.h" -#include "FBXDocument.h" -#include "FBXMeshGeometry.h" -#include "FBXImporter.h" -#include "FBXDocumentUtil.h" - -namespace Assimp { -namespace FBX { - -using namespace Util; - -// ------------------------------------------------------------------------------------------------ -Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name) - : Object(id,element,name) -{ - const Scope& sc = GetRequiredScope(element); - - const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2)); - props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true); -} - - -// ------------------------------------------------------------------------------------------------ -Deformer::~Deformer() -{ - -} - - -// ------------------------------------------------------------------------------------------------ -Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: Deformer(id,element,doc,name) -, node() -{ - const Scope& sc = GetRequiredScope(element); - - const Element* const Indexes = sc["Indexes"]; - const Element* const Weights = sc["Weights"]; - - const Element& Transform = GetRequiredElement(sc,"Transform",&element); - const Element& TransformLink = GetRequiredElement(sc,"TransformLink",&element); - - transform = ReadMatrix(Transform); - transformLink = ReadMatrix(TransformLink); - - // it is actually possible that there be Deformer's with no weights - if (!!Indexes != !!Weights) { - DOMError("either Indexes or Weights are missing from Cluster",&element); - } - - if(Indexes) { - ParseVectorDataArray(indices,*Indexes); - ParseVectorDataArray(weights,*Weights); - } - - if(indices.size() != weights.size()) { - DOMError("sizes of index and weight array don't match up",&element); - } - - // read assigned node - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Model"); - for(const Connection* con : conns) { - const Model* const mod = ProcessSimpleConnection<Model>(*con, false, "Model -> Cluster", element); - if(mod) { - node = mod; - break; - } - } - - if (!node) { - DOMError("failed to read target Node for Cluster",&element); - } -} - - -// ------------------------------------------------------------------------------------------------ -Cluster::~Cluster() -{ - -} - - -// ------------------------------------------------------------------------------------------------ -Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: Deformer(id,element,doc,name) -, accuracy( 0.0f ) { - const Scope& sc = GetRequiredScope(element); - - const Element* const Link_DeformAcuracy = sc["Link_DeformAcuracy"]; - if(Link_DeformAcuracy) { - accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0)); - } - - // resolve assigned clusters - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); - - clusters.reserve(conns.size()); - for(const Connection* con : conns) { - - const Cluster* const cluster = ProcessSimpleConnection<Cluster>(*con, false, "Cluster -> Skin", element); - if(cluster) { - clusters.push_back(cluster); - continue; - } - } -} - - -// ------------------------------------------------------------------------------------------------ -Skin::~Skin() -{ - -} -// ------------------------------------------------------------------------------------------------ -BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name) - : Deformer(id, element, doc, name) -{ - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(), "Deformer"); - blendShapeChannels.reserve(conns.size()); - for (const Connection* con : conns) { - const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element); - if (bspc) { - blendShapeChannels.push_back(bspc); - continue; - } - } -} -// ------------------------------------------------------------------------------------------------ -BlendShape::~BlendShape() -{ - -} -// ------------------------------------------------------------------------------------------------ -BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name) - : Deformer(id, element, doc, name) -{ - const Scope& sc = GetRequiredScope(element); - const Element* const DeformPercent = sc["DeformPercent"]; - if (DeformPercent) { - percent = ParseTokenAsFloat(GetRequiredToken(*DeformPercent, 0)); - } - const Element* const FullWeights = sc["FullWeights"]; - if (FullWeights) { - ParseVectorDataArray(fullWeights, *FullWeights); - } - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(), "Geometry"); - shapeGeometries.reserve(conns.size()); - for (const Connection* con : conns) { - const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element); - if (sg) { - shapeGeometries.push_back(sg); - continue; - } - } -} -// ------------------------------------------------------------------------------------------------ -BlendShapeChannel::~BlendShapeChannel() -{ - -} -// ------------------------------------------------------------------------------------------------ -} -} -#endif - diff --git a/thirdparty/assimp/code/FBX/FBXDocument.cpp b/thirdparty/assimp/code/FBX/FBXDocument.cpp deleted file mode 100644 index 506fd978dd..0000000000 --- a/thirdparty/assimp/code/FBX/FBXDocument.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the* - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXDocument.cpp - * @brief Implementation of the FBX DOM classes - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXDocument.h" -#include "FBXMeshGeometry.h" -#include "FBXParser.h" -#include "FBXUtil.h" -#include "FBXImporter.h" -#include "FBXImportSettings.h" -#include "FBXDocumentUtil.h" -#include "FBXProperties.h" - -#include <memory> -#include <functional> -#include <map> - -namespace Assimp { -namespace FBX { - -using namespace Util; - -// ------------------------------------------------------------------------------------------------ -LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) -: doc(doc) -, element(element) -, id(id) -, flags() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -LazyObject::~LazyObject() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -const Object* LazyObject::Get(bool dieOnError) -{ - if(IsBeingConstructed() || FailedToConstruct()) { - return nullptr; - } - - if (object.get()) { - return object.get(); - } - - const Token& key = element.KeyToken(); - const TokenList& tokens = element.Tokens(); - - if(tokens.size() < 3) { - DOMError("expected at least 3 tokens: id, name and class tag",&element); - } - - const char* err; - std::string name = ParseTokenAsString(*tokens[1],err); - if (err) { - DOMError(err,&element); - } - - // small fix for binary reading: binary fbx files don't use - // prefixes such as Model:: in front of their names. The - // loading code expects this at many places, though! - // so convert the binary representation (a 0x0001) to the - // double colon notation. - if(tokens[1]->IsBinary()) { - for (size_t i = 0; i < name.length(); ++i) { - if (name[i] == 0x0 && name[i+1] == 0x1) { - name = name.substr(i+2) + "::" + name.substr(0,i); - } - } - } - - const std::string classtag = ParseTokenAsString(*tokens[2],err); - if (err) { - DOMError(err,&element); - } - - // prevent recursive calls - flags |= BEING_CONSTRUCTED; - - try { - // this needs to be relatively fast since it happens a lot, - // so avoid constructing strings all the time. - const char* obtype = key.begin(); - const size_t length = static_cast<size_t>(key.end()-key.begin()); - - // For debugging - //dumpObjectClassInfo( objtype, classtag ); - - if (!strncmp(obtype,"Geometry",length)) { - if (!strcmp(classtag.c_str(),"Mesh")) { - object.reset(new MeshGeometry(id,element,name,doc)); - } - if (!strcmp(classtag.c_str(), "Shape")) { - object.reset(new ShapeGeometry(id, element, name, doc)); - } - if (!strcmp(classtag.c_str(), "Line")) { - object.reset(new LineGeometry(id, element, name, doc)); - } - } - else if (!strncmp(obtype,"NodeAttribute",length)) { - if (!strcmp(classtag.c_str(),"Camera")) { - object.reset(new Camera(id,element,doc,name)); - } - else if (!strcmp(classtag.c_str(),"CameraSwitcher")) { - object.reset(new CameraSwitcher(id,element,doc,name)); - } - else if (!strcmp(classtag.c_str(),"Light")) { - object.reset(new Light(id,element,doc,name)); - } - else if (!strcmp(classtag.c_str(),"Null")) { - object.reset(new Null(id,element,doc,name)); - } - else if (!strcmp(classtag.c_str(),"LimbNode")) { - object.reset(new LimbNode(id,element,doc,name)); - } - } - else if (!strncmp(obtype,"Deformer",length)) { - if (!strcmp(classtag.c_str(),"Cluster")) { - object.reset(new Cluster(id,element,doc,name)); - } - else if (!strcmp(classtag.c_str(),"Skin")) { - object.reset(new Skin(id,element,doc,name)); - } - else if (!strcmp(classtag.c_str(), "BlendShape")) { - object.reset(new BlendShape(id, element, doc, name)); - } - else if (!strcmp(classtag.c_str(), "BlendShapeChannel")) { - object.reset(new BlendShapeChannel(id, element, doc, name)); - } - } - else if ( !strncmp( obtype, "Model", length ) ) { - // FK and IK effectors are not supported - if ( strcmp( classtag.c_str(), "IKEffector" ) && strcmp( classtag.c_str(), "FKEffector" ) ) { - object.reset( new Model( id, element, doc, name ) ); - } - } - else if (!strncmp(obtype,"Material",length)) { - object.reset(new Material(id,element,doc,name)); - } - else if (!strncmp(obtype,"Texture",length)) { - object.reset(new Texture(id,element,doc,name)); - } - else if (!strncmp(obtype,"LayeredTexture",length)) { - object.reset(new LayeredTexture(id,element,doc,name)); - } - else if (!strncmp(obtype,"Video",length)) { - object.reset(new Video(id,element,doc,name)); - } - else if (!strncmp(obtype,"AnimationStack",length)) { - object.reset(new AnimationStack(id,element,name,doc)); - } - else if (!strncmp(obtype,"AnimationLayer",length)) { - object.reset(new AnimationLayer(id,element,name,doc)); - } - // note: order matters for these two - else if (!strncmp(obtype,"AnimationCurve",length)) { - object.reset(new AnimationCurve(id,element,name,doc)); - } - else if (!strncmp(obtype,"AnimationCurveNode",length)) { - object.reset(new AnimationCurveNode(id,element,name,doc)); - } - } - catch(std::exception& ex) { - flags &= ~BEING_CONSTRUCTED; - flags |= FAILED_TO_CONSTRUCT; - - if(dieOnError || doc.Settings().strictMode) { - throw; - } - - // note: the error message is already formatted, so raw logging is ok - if(!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR(ex.what()); - } - return NULL; - } - - if (!object.get()) { - //DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element); - } - - flags &= ~BEING_CONSTRUCTED; - return object.get(); -} - -// ------------------------------------------------------------------------------------------------ -Object::Object(uint64_t id, const Element& element, const std::string& name) -: element(element) -, name(name) -, id(id) -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -Object::~Object() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props) -: props(props) -, doc(doc) -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -FileGlobalSettings::~FileGlobalSettings() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -Document::Document(const Parser& parser, const ImportSettings& settings) -: settings(settings) -, parser(parser) -{ - // Cannot use array default initialization syntax because vc8 fails on it - for (auto &timeStamp : creationTimeStamp) { - timeStamp = 0; - } - - ReadHeader(); - ReadPropertyTemplates(); - - ReadGlobalSettings(); - - // This order is important, connections need parsed objects to check - // whether connections are ok or not. Objects may not be evaluated yet, - // though, since this may require valid connections. - ReadObjects(); - ReadConnections(); -} - -// ------------------------------------------------------------------------------------------------ -Document::~Document() -{ - for(ObjectMap::value_type& v : objects) { - delete v.second; - } - - for(ConnectionMap::value_type& v : src_connections) { - delete v.second; - } - // |dest_connections| contain the same Connection objects as the |src_connections| -} - -// ------------------------------------------------------------------------------------------------ -static const unsigned int LowerSupportedVersion = 7100; -static const unsigned int UpperSupportedVersion = 7400; - -void Document::ReadHeader() { - // Read ID objects from "Objects" section - const Scope& sc = parser.GetRootScope(); - const Element* const ehead = sc["FBXHeaderExtension"]; - if(!ehead || !ehead->Compound()) { - DOMError("no FBXHeaderExtension dictionary found"); - } - - const Scope& shead = *ehead->Compound(); - fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0)); - - // While we may have some success with newer files, we don't support - // the older 6.n fbx format - if(fbxVersion < LowerSupportedVersion ) { - DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013"); - } - if(fbxVersion > UpperSupportedVersion ) { - if(Settings().strictMode) { - DOMError("unsupported, newer format version, supported are only FBX 2011, FBX 2012 and FBX 2013" - " (turn off strict mode to try anyhow) "); - } - else { - DOMWarning("unsupported, newer format version, supported are only FBX 2011, FBX 2012 and FBX 2013," - " trying to read it nevertheless"); - } - } - - const Element* const ecreator = shead["Creator"]; - if(ecreator) { - creator = ParseTokenAsString(GetRequiredToken(*ecreator,0)); - } - - const Element* const etimestamp = shead["CreationTimeStamp"]; - if(etimestamp && etimestamp->Compound()) { - const Scope& stimestamp = *etimestamp->Compound(); - creationTimeStamp[0] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Year"),0)); - creationTimeStamp[1] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Month"),0)); - creationTimeStamp[2] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Day"),0)); - creationTimeStamp[3] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Hour"),0)); - creationTimeStamp[4] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Minute"),0)); - creationTimeStamp[5] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Second"),0)); - creationTimeStamp[6] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Millisecond"),0)); - } -} - -// ------------------------------------------------------------------------------------------------ -void Document::ReadGlobalSettings() -{ - const Scope& sc = parser.GetRootScope(); - const Element* const ehead = sc["GlobalSettings"]; - if ( nullptr == ehead || !ehead->Compound() ) { - DOMWarning( "no GlobalSettings dictionary found" ); - globals.reset(new FileGlobalSettings(*this, std::make_shared<const PropertyTable>())); - return; - } - - std::shared_ptr<const PropertyTable> props = GetPropertyTable( *this, "", *ehead, *ehead->Compound(), true ); - - //double v = PropertyGet<float>( *props.get(), std::string("UnitScaleFactor"), 1.0 ); - - if(!props) { - DOMError("GlobalSettings dictionary contains no property table"); - } - - globals.reset(new FileGlobalSettings(*this, props)); -} - -// ------------------------------------------------------------------------------------------------ -void Document::ReadObjects() -{ - // read ID objects from "Objects" section - const Scope& sc = parser.GetRootScope(); - const Element* const eobjects = sc["Objects"]; - if(!eobjects || !eobjects->Compound()) { - DOMError("no Objects dictionary found"); - } - - // add a dummy entry to represent the Model::RootNode object (id 0), - // which is only indirectly defined in the input file - objects[0] = new LazyObject(0L, *eobjects, *this); - - const Scope& sobjects = *eobjects->Compound(); - for(const ElementMap::value_type& el : sobjects.Elements()) { - - // extract ID - const TokenList& tok = el.second->Tokens(); - - if (tok.empty()) { - DOMError("expected ID after object key",el.second); - } - - const char* err; - const uint64_t id = ParseTokenAsID(*tok[0], err); - if(err) { - DOMError(err,el.second); - } - - // id=0 is normally implicit - if(id == 0L) { - DOMError("encountered object with implicitly defined id 0",el.second); - } - - if(objects.find(id) != objects.end()) { - DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second); - } - - objects[id] = new LazyObject(id, *el.second, *this); - - // grab all animation stacks upfront since there is no listing of them - if(!strcmp(el.first.c_str(),"AnimationStack")) { - animationStacks.push_back(id); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void Document::ReadPropertyTemplates() -{ - const Scope& sc = parser.GetRootScope(); - // read property templates from "Definitions" section - const Element* const edefs = sc["Definitions"]; - if(!edefs || !edefs->Compound()) { - DOMWarning("no Definitions dictionary found"); - return; - } - - const Scope& sdefs = *edefs->Compound(); - const ElementCollection otypes = sdefs.GetCollection("ObjectType"); - for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) { - const Element& el = *(*it).second; - const Scope* sc = el.Compound(); - if(!sc) { - DOMWarning("expected nested scope in ObjectType, ignoring",&el); - continue; - } - - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - DOMWarning("expected name for ObjectType element, ignoring",&el); - continue; - } - - const std::string& oname = ParseTokenAsString(*tok[0]); - - const ElementCollection templs = sc->GetCollection("PropertyTemplate"); - for(ElementMap::const_iterator it = templs.first; it != templs.second; ++it) { - const Element& el = *(*it).second; - const Scope* sc = el.Compound(); - if(!sc) { - DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el); - continue; - } - - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - DOMWarning("expected name for PropertyTemplate element, ignoring",&el); - continue; - } - - const std::string& pname = ParseTokenAsString(*tok[0]); - - const Element* Properties70 = (*sc)["Properties70"]; - if(Properties70) { - std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>( - *Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL)) - ); - - templates[oname+"."+pname] = props; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -void Document::ReadConnections() -{ - const Scope& sc = parser.GetRootScope(); - // read property templates from "Definitions" section - const Element* const econns = sc["Connections"]; - if(!econns || !econns->Compound()) { - DOMError("no Connections dictionary found"); - } - - uint64_t insertionOrder = 0l; - const Scope& sconns = *econns->Compound(); - const ElementCollection conns = sconns.GetCollection("C"); - for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) { - const Element& el = *(*it).second; - const std::string& type = ParseTokenAsString(GetRequiredToken(el,0)); - - // PP = property-property connection, ignored for now - // (tokens: "PP", ID1, "Property1", ID2, "Property2") - if ( type == "PP" ) { - continue; - } - - const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1)); - const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2)); - - // OO = object-object connection - // OP = object-property connection, in which case the destination property follows the object ID - const std::string& prop = (type == "OP" ? ParseTokenAsString(GetRequiredToken(el,3)) : ""); - - if(objects.find(src) == objects.end()) { - DOMWarning("source object for connection does not exist",&el); - continue; - } - - // dest may be 0 (root node) but we added a dummy object before - if(objects.find(dest) == objects.end()) { - DOMWarning("destination object for connection does not exist",&el); - continue; - } - - // add new connection - const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this); - src_connections.insert(ConnectionMap::value_type(src,c)); - dest_connections.insert(ConnectionMap::value_type(dest,c)); - } -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<const AnimationStack*>& Document::AnimationStacks() const -{ - if (!animationStacksResolved.empty() || animationStacks.empty()) { - return animationStacksResolved; - } - - animationStacksResolved.reserve(animationStacks.size()); - for(uint64_t id : animationStacks) { - LazyObject* const lazy = GetObject(id); - const AnimationStack* stack; - if(!lazy || !(stack = lazy->Get<AnimationStack>())) { - DOMWarning("failed to read AnimationStack object"); - continue; - } - animationStacksResolved.push_back(stack); - } - - return animationStacksResolved; -} - -// ------------------------------------------------------------------------------------------------ -LazyObject* Document::GetObject(uint64_t id) const -{ - ObjectMap::const_iterator it = objects.find(id); - return it == objects.end() ? nullptr : (*it).second; -} - -#define MAX_CLASSNAMES 6 - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const -{ - std::vector<const Connection*> temp; - - const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = - conns.equal_range(id); - - temp.reserve(std::distance(range.first,range.second)); - for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) { - temp.push_back((*it).second); - } - - std::sort(temp.begin(), temp.end(), std::mem_fn(&Connection::Compare)); - - return temp; // NRVO should handle this -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src, - const ConnectionMap& conns, - const char* const* classnames, - size_t count) const - -{ - ai_assert(classnames); - ai_assert( count != 0 ); - ai_assert( count <= MAX_CLASSNAMES); - - size_t lengths[MAX_CLASSNAMES]; - - const size_t c = count; - for (size_t i = 0; i < c; ++i) { - lengths[ i ] = strlen(classnames[i]); - } - - std::vector<const Connection*> temp; - const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = - conns.equal_range(id); - - temp.reserve(std::distance(range.first,range.second)); - for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) { - const Token& key = (is_src - ? (*it).second->LazyDestinationObject() - : (*it).second->LazySourceObject() - ).GetElement().KeyToken(); - - const char* obtype = key.begin(); - - for (size_t i = 0; i < c; ++i) { - ai_assert(classnames[i]); - if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lengths[i] && !strncmp(classnames[i],obtype,lengths[i])) { - obtype = nullptr; - break; - } - } - - if(obtype) { - continue; - } - - temp.push_back((*it).second); - } - - std::sort(temp.begin(), temp.end(), std::mem_fn(&Connection::Compare)); - return temp; // NRVO should handle this -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const -{ - return GetConnectionsSequenced(source, ConnectionsBySource()); -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t src, const char* classname) const -{ - const char* arr[] = {classname}; - return GetConnectionsBySourceSequenced(src, arr,1); -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source, - const char* const* classnames, size_t count) const -{ - return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count); -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest, - const char* classname) const -{ - const char* arr[] = {classname}; - return GetConnectionsByDestinationSequenced(dest, arr,1); -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const -{ - return GetConnectionsSequenced(dest, ConnectionsByDestination()); -} - -// ------------------------------------------------------------------------------------------------ -std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest, - const char* const* classnames, size_t count) const - -{ - return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count); -} - -// ------------------------------------------------------------------------------------------------ -Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, - const Document& doc) - -: insertionOrder(insertionOrder) -, prop(prop) -, src(src) -, dest(dest) -, doc(doc) -{ - ai_assert(doc.Objects().find(src) != doc.Objects().end()); - // dest may be 0 (root node) - ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end()); -} - -// ------------------------------------------------------------------------------------------------ -Connection::~Connection() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -LazyObject& Connection::LazySourceObject() const -{ - LazyObject* const lazy = doc.GetObject(src); - ai_assert(lazy); - return *lazy; -} - -// ------------------------------------------------------------------------------------------------ -LazyObject& Connection::LazyDestinationObject() const -{ - LazyObject* const lazy = doc.GetObject(dest); - ai_assert(lazy); - return *lazy; -} - -// ------------------------------------------------------------------------------------------------ -const Object* Connection::SourceObject() const -{ - LazyObject* const lazy = doc.GetObject(src); - ai_assert(lazy); - return lazy->Get(); -} - -// ------------------------------------------------------------------------------------------------ -const Object* Connection::DestinationObject() const -{ - LazyObject* const lazy = doc.GetObject(dest); - ai_assert(lazy); - return lazy->Get(); -} - -} // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXDocument.h b/thirdparty/assimp/code/FBX/FBXDocument.h deleted file mode 100644 index a60d7d9efa..0000000000 --- a/thirdparty/assimp/code/FBX/FBXDocument.h +++ /dev/null @@ -1,1215 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXDocument.h - * @brief FBX DOM - */ -#ifndef INCLUDED_AI_FBX_DOCUMENT_H -#define INCLUDED_AI_FBX_DOCUMENT_H - -#include <numeric> -#include <stdint.h> -#include <assimp/mesh.h> -#include "FBXProperties.h" -#include "FBXParser.h" - -#define _AI_CONCAT(a,b) a ## b -#define AI_CONCAT(a,b) _AI_CONCAT(a,b) - -namespace Assimp { -namespace FBX { - -class Parser; -class Object; -struct ImportSettings; - -class PropertyTable; -class Document; -class Material; -class ShapeGeometry; -class LineGeometry; -class Geometry; - -class Video; - -class AnimationCurve; -class AnimationCurveNode; -class AnimationLayer; -class AnimationStack; - -class BlendShapeChannel; -class BlendShape; -class Skin; -class Cluster; - - -/** Represents a delay-parsed FBX objects. Many objects in the scene - * are not needed by assimp, so it makes no sense to parse them - * upfront. */ -class LazyObject { -public: - LazyObject(uint64_t id, const Element& element, const Document& doc); - - ~LazyObject(); - - const Object* Get(bool dieOnError = false); - - template <typename T> - const T* Get(bool dieOnError = false) { - const Object* const ob = Get(dieOnError); - return ob ? dynamic_cast<const T*>(ob) : NULL; - } - - uint64_t ID() const { - return id; - } - - bool IsBeingConstructed() const { - return (flags & BEING_CONSTRUCTED) != 0; - } - - bool FailedToConstruct() const { - return (flags & FAILED_TO_CONSTRUCT) != 0; - } - - const Element& GetElement() const { - return element; - } - - const Document& GetDocument() const { - return doc; - } - -private: - const Document& doc; - const Element& element; - std::unique_ptr<const Object> object; - - const uint64_t id; - - enum Flags { - BEING_CONSTRUCTED = 0x1, - FAILED_TO_CONSTRUCT = 0x2 - }; - - unsigned int flags; -}; - -/** Base class for in-memory (DOM) representations of FBX objects */ -class Object { -public: - Object(uint64_t id, const Element& element, const std::string& name); - - virtual ~Object(); - - const Element& SourceElement() const { - return element; - } - - const std::string& Name() const { - return name; - } - - uint64_t ID() const { - return id; - } - -protected: - const Element& element; - const std::string name; - const uint64_t id; -}; - -/** DOM class for generic FBX NoteAttribute blocks. NoteAttribute's just hold a property table, - * fixed members are added by deriving classes. */ -class NodeAttribute : public Object { -public: - NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~NodeAttribute(); - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - -private: - std::shared_ptr<const PropertyTable> props; -}; - -/** DOM base class for FBX camera settings attached to a node */ -class CameraSwitcher : public NodeAttribute { -public: - CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~CameraSwitcher(); - - int CameraID() const { - return cameraId; - } - - const std::string& CameraName() const { - return cameraName; - } - - const std::string& CameraIndexName() const { - return cameraIndexName; - } - -private: - int cameraId; - std::string cameraName; - std::string cameraIndexName; -}; - -#define fbx_stringize(a) #a - -#define fbx_simple_property(name, type, default_value) \ - type name() const { \ - return PropertyGet<type>(Props(), fbx_stringize(name), (default_value)); \ - } - -// XXX improve logging -#define fbx_simple_enum_property(name, type, default_value) \ - type name() const { \ - const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \ - if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \ - ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \ - return static_cast<type>(default_value); \ - } \ - return static_cast<type>(ival); \ -} - - -/** DOM base class for FBX cameras attached to a node */ -class Camera : public NodeAttribute { -public: - Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Camera(); - - fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0)) - fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0)) - fbx_simple_property(InterestPosition, aiVector3D, aiVector3D(0,0,0)) - - fbx_simple_property(AspectWidth, float, 1.0f) - fbx_simple_property(AspectHeight, float, 1.0f) - fbx_simple_property(FilmWidth, float, 1.0f) - fbx_simple_property(FilmHeight, float, 1.0f) - - fbx_simple_property(NearPlane, float, 0.1f) - fbx_simple_property(FarPlane, float, 100.0f) - - fbx_simple_property(FilmAspectRatio, float, 1.0f) - fbx_simple_property(ApertureMode, int, 0) - - fbx_simple_property(FieldOfView, float, 1.0f) - fbx_simple_property(FocalLength, float, 1.0f) -}; - -/** DOM base class for FBX null markers attached to a node */ -class Null : public NodeAttribute { -public: - Null(uint64_t id, const Element& element, const Document& doc, const std::string& name); - virtual ~Null(); -}; - -/** DOM base class for FBX limb node markers attached to a node */ -class LimbNode : public NodeAttribute { -public: - LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name); - virtual ~LimbNode(); -}; - -/** DOM base class for FBX lights attached to a node */ -class Light : public NodeAttribute { -public: - Light(uint64_t id, const Element& element, const Document& doc, const std::string& name); - virtual ~Light(); - - enum Type - { - Type_Point, - Type_Directional, - Type_Spot, - Type_Area, - Type_Volume, - - Type_MAX // end-of-enum sentinel - }; - - enum Decay - { - Decay_None, - Decay_Linear, - Decay_Quadratic, - Decay_Cubic, - - Decay_MAX // end-of-enum sentinel - }; - - fbx_simple_property(Color, aiVector3D, aiVector3D(1,1,1)) - fbx_simple_enum_property(LightType, Type, 0) - fbx_simple_property(CastLightOnObject, bool, false) - fbx_simple_property(DrawVolumetricLight, bool, true) - fbx_simple_property(DrawGroundProjection, bool, true) - fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false) - fbx_simple_property(Intensity, float, 100.0f) - fbx_simple_property(InnerAngle, float, 0.0f) - fbx_simple_property(OuterAngle, float, 45.0f) - fbx_simple_property(Fog, int, 50) - fbx_simple_enum_property(DecayType, Decay, 2) - fbx_simple_property(DecayStart, float, 1.0f) - fbx_simple_property(FileName, std::string, "") - - fbx_simple_property(EnableNearAttenuation, bool, false) - fbx_simple_property(NearAttenuationStart, float, 0.0f) - fbx_simple_property(NearAttenuationEnd, float, 0.0f) - fbx_simple_property(EnableFarAttenuation, bool, false) - fbx_simple_property(FarAttenuationStart, float, 0.0f) - fbx_simple_property(FarAttenuationEnd, float, 0.0f) - - fbx_simple_property(CastShadows, bool, true) - fbx_simple_property(ShadowColor, aiVector3D, aiVector3D(0,0,0)) - - fbx_simple_property(AreaLightShape, int, 0) - - fbx_simple_property(LeftBarnDoor, float, 20.0f) - fbx_simple_property(RightBarnDoor, float, 20.0f) - fbx_simple_property(TopBarnDoor, float, 20.0f) - fbx_simple_property(BottomBarnDoor, float, 20.0f) - fbx_simple_property(EnableBarnDoor, bool, true) -}; - -/** DOM base class for FBX models (even though its semantics are more "node" than "model" */ -class Model : public Object { -public: - enum RotOrder { - RotOrder_EulerXYZ = 0, - RotOrder_EulerXZY, - RotOrder_EulerYZX, - RotOrder_EulerYXZ, - RotOrder_EulerZXY, - RotOrder_EulerZYX, - - RotOrder_SphericXYZ, - - RotOrder_MAX // end-of-enum sentinel - }; - - enum TransformInheritance { - TransformInheritance_RrSs = 0, - TransformInheritance_RSrs, - TransformInheritance_Rrs, - - TransformInheritance_MAX // end-of-enum sentinel - }; - - Model(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Model(); - - fbx_simple_property(QuaternionInterpolate, int, 0) - - fbx_simple_property(RotationOffset, aiVector3D, aiVector3D()) - fbx_simple_property(RotationPivot, aiVector3D, aiVector3D()) - fbx_simple_property(ScalingOffset, aiVector3D, aiVector3D()) - fbx_simple_property(ScalingPivot, aiVector3D, aiVector3D()) - fbx_simple_property(TranslationActive, bool, false) - - fbx_simple_property(TranslationMin, aiVector3D, aiVector3D()) - fbx_simple_property(TranslationMax, aiVector3D, aiVector3D()) - - fbx_simple_property(TranslationMinX, bool, false) - fbx_simple_property(TranslationMaxX, bool, false) - fbx_simple_property(TranslationMinY, bool, false) - fbx_simple_property(TranslationMaxY, bool, false) - fbx_simple_property(TranslationMinZ, bool, false) - fbx_simple_property(TranslationMaxZ, bool, false) - - fbx_simple_enum_property(RotationOrder, RotOrder, 0) - fbx_simple_property(RotationSpaceForLimitOnly, bool, false) - fbx_simple_property(RotationStiffnessX, float, 0.0f) - fbx_simple_property(RotationStiffnessY, float, 0.0f) - fbx_simple_property(RotationStiffnessZ, float, 0.0f) - fbx_simple_property(AxisLen, float, 0.0f) - - fbx_simple_property(PreRotation, aiVector3D, aiVector3D()) - fbx_simple_property(PostRotation, aiVector3D, aiVector3D()) - fbx_simple_property(RotationActive, bool, false) - - fbx_simple_property(RotationMin, aiVector3D, aiVector3D()) - fbx_simple_property(RotationMax, aiVector3D, aiVector3D()) - - fbx_simple_property(RotationMinX, bool, false) - fbx_simple_property(RotationMaxX, bool, false) - fbx_simple_property(RotationMinY, bool, false) - fbx_simple_property(RotationMaxY, bool, false) - fbx_simple_property(RotationMinZ, bool, false) - fbx_simple_property(RotationMaxZ, bool, false) - fbx_simple_enum_property(InheritType, TransformInheritance, 0) - - fbx_simple_property(ScalingActive, bool, false) - fbx_simple_property(ScalingMin, aiVector3D, aiVector3D()) - fbx_simple_property(ScalingMax, aiVector3D, aiVector3D(1.f,1.f,1.f)) - fbx_simple_property(ScalingMinX, bool, false) - fbx_simple_property(ScalingMaxX, bool, false) - fbx_simple_property(ScalingMinY, bool, false) - fbx_simple_property(ScalingMaxY, bool, false) - fbx_simple_property(ScalingMinZ, bool, false) - fbx_simple_property(ScalingMaxZ, bool, false) - - fbx_simple_property(GeometricTranslation, aiVector3D, aiVector3D()) - fbx_simple_property(GeometricRotation, aiVector3D, aiVector3D()) - fbx_simple_property(GeometricScaling, aiVector3D, aiVector3D(1.f, 1.f, 1.f)) - - fbx_simple_property(MinDampRangeX, float, 0.0f) - fbx_simple_property(MinDampRangeY, float, 0.0f) - fbx_simple_property(MinDampRangeZ, float, 0.0f) - fbx_simple_property(MaxDampRangeX, float, 0.0f) - fbx_simple_property(MaxDampRangeY, float, 0.0f) - fbx_simple_property(MaxDampRangeZ, float, 0.0f) - - fbx_simple_property(MinDampStrengthX, float, 0.0f) - fbx_simple_property(MinDampStrengthY, float, 0.0f) - fbx_simple_property(MinDampStrengthZ, float, 0.0f) - fbx_simple_property(MaxDampStrengthX, float, 0.0f) - fbx_simple_property(MaxDampStrengthY, float, 0.0f) - fbx_simple_property(MaxDampStrengthZ, float, 0.0f) - - fbx_simple_property(PreferredAngleX, float, 0.0f) - fbx_simple_property(PreferredAngleY, float, 0.0f) - fbx_simple_property(PreferredAngleZ, float, 0.0f) - - fbx_simple_property(Show, bool, true) - fbx_simple_property(LODBox, bool, false) - fbx_simple_property(Freeze, bool, false) - - const std::string& Shading() const { - return shading; - } - - const std::string& Culling() const { - return culling; - } - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - /** Get material links */ - const std::vector<const Material*>& GetMaterials() const { - return materials; - } - - /** Get geometry links */ - const std::vector<const Geometry*>& GetGeometry() const { - return geometry; - } - - /** Get node attachments */ - const std::vector<const NodeAttribute*>& GetAttributes() const { - return attributes; - } - - /** convenience method to check if the node has a Null node marker */ - bool IsNull() const; - -private: - void ResolveLinks(const Element& element, const Document& doc); - -private: - std::vector<const Material*> materials; - std::vector<const Geometry*> geometry; - std::vector<const NodeAttribute*> attributes; - - std::string shading; - std::string culling; - std::shared_ptr<const PropertyTable> props; -}; - -/** DOM class for generic FBX textures */ -class Texture : public Object { -public: - Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Texture(); - - const std::string& Type() const { - return type; - } - - const std::string& FileName() const { - return fileName; - } - - const std::string& RelativeFilename() const { - return relativeFileName; - } - - const std::string& AlphaSource() const { - return alphaSource; - } - - const aiVector2D& UVTranslation() const { - return uvTrans; - } - - const aiVector2D& UVScaling() const { - return uvScaling; - } - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - // return a 4-tuple - const unsigned int* Crop() const { - return crop; - } - - const Video* Media() const { - return media; - } - -private: - aiVector2D uvTrans; - aiVector2D uvScaling; - - std::string type; - std::string relativeFileName; - std::string fileName; - std::string alphaSource; - std::shared_ptr<const PropertyTable> props; - - unsigned int crop[4]; - - const Video* media; -}; - -/** DOM class for layered FBX textures */ -class LayeredTexture : public Object { -public: - LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name); - virtual ~LayeredTexture(); - - // Can only be called after construction of the layered texture object due to construction flag. - void fillTexture(const Document& doc); - - enum BlendMode { - BlendMode_Translucent, - BlendMode_Additive, - BlendMode_Modulate, - BlendMode_Modulate2, - BlendMode_Over, - BlendMode_Normal, - BlendMode_Dissolve, - BlendMode_Darken, - BlendMode_ColorBurn, - BlendMode_LinearBurn, - BlendMode_DarkerColor, - BlendMode_Lighten, - BlendMode_Screen, - BlendMode_ColorDodge, - BlendMode_LinearDodge, - BlendMode_LighterColor, - BlendMode_SoftLight, - BlendMode_HardLight, - BlendMode_VividLight, - BlendMode_LinearLight, - BlendMode_PinLight, - BlendMode_HardMix, - BlendMode_Difference, - BlendMode_Exclusion, - BlendMode_Subtract, - BlendMode_Divide, - BlendMode_Hue, - BlendMode_Saturation, - BlendMode_Color, - BlendMode_Luminosity, - BlendMode_Overlay, - BlendMode_BlendModeCount - }; - - const Texture* getTexture(int index=0) const - { - return textures[index]; - - } - int textureCount() const { - return static_cast<int>(textures.size()); - } - BlendMode GetBlendMode() const - { - return blendMode; - } - float Alpha() - { - return alpha; - } -private: - std::vector<const Texture*> textures; - BlendMode blendMode; - float alpha; -}; - -typedef std::fbx_unordered_map<std::string, const Texture*> TextureMap; -typedef std::fbx_unordered_map<std::string, const LayeredTexture*> LayeredTextureMap; - - -/** DOM class for generic FBX videos */ -class Video : public Object { -public: - Video(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Video(); - - const std::string& Type() const { - return type; - } - - const std::string& FileName() const { - return fileName; - } - - const std::string& RelativeFilename() const { - return relativeFileName; - } - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - const uint8_t* Content() const { - ai_assert(content); - return content; - } - - uint64_t ContentLength() const { - return contentLength; - } - - uint8_t* RelinquishContent() { - uint8_t* ptr = content; - content = 0; - return ptr; - } - - bool operator==(const Video& other) const - { - return ( - type == other.type - && relativeFileName == other.relativeFileName - && fileName == other.fileName - ); - } - - bool operator<(const Video& other) const - { - return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName); - } - -private: - std::string type; - std::string relativeFileName; - std::string fileName; - std::shared_ptr<const PropertyTable> props; - - uint64_t contentLength; - uint8_t* content; -}; - -/** DOM class for generic FBX materials */ -class Material : public Object { -public: - Material(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Material(); - - const std::string& GetShadingModel() const { - return shading; - } - - bool IsMultilayer() const { - return multilayer; - } - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - const TextureMap& Textures() const { - return textures; - } - - const LayeredTextureMap& LayeredTextures() const { - return layeredTextures; - } - -private: - std::string shading; - bool multilayer; - std::shared_ptr<const PropertyTable> props; - - TextureMap textures; - LayeredTextureMap layeredTextures; -}; - -typedef std::vector<int64_t> KeyTimeList; -typedef std::vector<float> KeyValueList; - -/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */ -class AnimationCurve : public Object { -public: - AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc); - virtual ~AnimationCurve(); - - /** get list of keyframe positions (time). - * Invariant: |GetKeys()| > 0 */ - const KeyTimeList& GetKeys() const { - return keys; - } - - /** get list of keyframe values. - * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/ - const KeyValueList& GetValues() const { - return values; - } - - const std::vector<float>& GetAttributes() const { - return attributes; - } - - const std::vector<unsigned int>& GetFlags() const { - return flags; - } - -private: - KeyTimeList keys; - KeyValueList values; - std::vector<float> attributes; - std::vector<unsigned int> flags; -}; - -// property-name -> animation curve -typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap; - -/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */ -class AnimationCurveNode : public Object { -public: - /* the optional white list specifies a list of property names for which the caller - wants animations for. If the curve node does not match one of these, std::range_error - will be thrown. */ - AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, - const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0); - - virtual ~AnimationCurveNode(); - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - - const AnimationCurveMap& Curves() const; - - /** Object the curve is assigned to, this can be NULL if the - * target object has no DOM representation or could not - * be read for other reasons.*/ - const Object* Target() const { - return target; - } - - const Model* TargetAsModel() const { - return dynamic_cast<const Model*>(target); - } - - const NodeAttribute* TargetAsNodeAttribute() const { - return dynamic_cast<const NodeAttribute*>(target); - } - - /** Property of Target() that is being animated*/ - const std::string& TargetProperty() const { - return prop; - } - -private: - const Object* target; - std::shared_ptr<const PropertyTable> props; - mutable AnimationCurveMap curves; - - std::string prop; - const Document& doc; -}; - -typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList; - -/** Represents a FBX animation layer (i.e. a list of node animations) */ -class AnimationLayer : public Object { -public: - AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc); - virtual ~AnimationLayer(); - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - /* the optional white list specifies a list of property names for which the caller - wants animations for. Curves not matching this list will not be added to the - animation layer. */ - AnimationCurveNodeList Nodes(const char* const * target_prop_whitelist = nullptr, size_t whitelist_size = 0) const; - -private: - std::shared_ptr<const PropertyTable> props; - const Document& doc; -}; - -typedef std::vector<const AnimationLayer*> AnimationLayerList; - -/** Represents a FBX animation stack (i.e. a list of animation layers) */ -class AnimationStack : public Object { -public: - AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc); - virtual ~AnimationStack(); - - fbx_simple_property(LocalStart, int64_t, 0L) - fbx_simple_property(LocalStop, int64_t, 0L) - fbx_simple_property(ReferenceStart, int64_t, 0L) - fbx_simple_property(ReferenceStop, int64_t, 0L) - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - const AnimationLayerList& Layers() const { - return layers; - } - -private: - std::shared_ptr<const PropertyTable> props; - AnimationLayerList layers; -}; - - -/** DOM class for deformers */ -class Deformer : public Object { -public: - Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name); - virtual ~Deformer(); - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - -private: - std::shared_ptr<const PropertyTable> props; -}; - -typedef std::vector<float> WeightArray; -typedef std::vector<unsigned int> WeightIndexArray; - - -/** DOM class for BlendShapeChannel deformers */ -class BlendShapeChannel : public Deformer { -public: - BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~BlendShapeChannel(); - - float DeformPercent() const { - return percent; - } - - const WeightArray& GetFullWeights() const { - return fullWeights; - } - - const std::vector<const ShapeGeometry*>& GetShapeGeometries() const { - return shapeGeometries; - } - -private: - float percent; - WeightArray fullWeights; - std::vector<const ShapeGeometry*> shapeGeometries; -}; - -/** DOM class for BlendShape deformers */ -class BlendShape : public Deformer { -public: - BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~BlendShape(); - - const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const { - return blendShapeChannels; - } - -private: - std::vector<const BlendShapeChannel*> blendShapeChannels; -}; - -/** DOM class for skin deformer clusters (aka sub-deformers) */ -class Cluster : public Deformer { -public: - Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Cluster(); - - /** get the list of deformer weights associated with this cluster. - * Use #GetIndices() to get the associated vertices. Both arrays - * have the same size (and may also be empty). */ - const WeightArray& GetWeights() const { - return weights; - } - - /** get indices into the vertex data of the geometry associated - * with this cluster. Use #GetWeights() to get the associated weights. - * Both arrays have the same size (and may also be empty). */ - const WeightIndexArray& GetIndices() const { - return indices; - } - - /** */ - const aiMatrix4x4& Transform() const { - return transform; - } - - const aiMatrix4x4& TransformLink() const { - return transformLink; - } - - const Model* TargetNode() const { - return node; - } - -private: - WeightArray weights; - WeightIndexArray indices; - - aiMatrix4x4 transform; - aiMatrix4x4 transformLink; - - const Model* node; -}; - -/** DOM class for skin deformers */ -class Skin : public Deformer { -public: - Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name); - - virtual ~Skin(); - - float DeformAccuracy() const { - return accuracy; - } - - const std::vector<const Cluster*>& Clusters() const { - return clusters; - } - -private: - float accuracy; - std::vector<const Cluster*> clusters; -}; - -/** Represents a link between two FBX objects. */ -class Connection { -public: - Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, const Document& doc); - - ~Connection(); - - // note: a connection ensures that the source and dest objects exist, but - // not that they have DOM representations, so the return value of one of - // these functions can still be NULL. - const Object* SourceObject() const; - const Object* DestinationObject() const; - - // these, however, are always guaranteed to be valid - LazyObject& LazySourceObject() const; - LazyObject& LazyDestinationObject() const; - - - /** return the name of the property the connection is attached to. - * this is an empty string for object to object (OO) connections. */ - const std::string& PropertyName() const { - return prop; - } - - uint64_t InsertionOrder() const { - return insertionOrder; - } - - int CompareTo(const Connection* c) const { - ai_assert( nullptr != c ); - - // note: can't subtract because this would overflow uint64_t - if(InsertionOrder() > c->InsertionOrder()) { - return 1; - } - else if(InsertionOrder() < c->InsertionOrder()) { - return -1; - } - return 0; - } - - bool Compare(const Connection* c) const { - ai_assert( nullptr != c ); - - return InsertionOrder() < c->InsertionOrder(); - } - -public: - uint64_t insertionOrder; - const std::string prop; - - uint64_t src, dest; - const Document& doc; -}; - -// XXX again, unique_ptr would be useful. shared_ptr is too -// bloated since the objects have a well-defined single owner -// during their entire lifetime (Document). FBX files have -// up to many thousands of objects (most of which we never use), -// so the memory overhead for them should be kept at a minimum. -typedef std::fbx_unordered_map<uint64_t, LazyObject*> ObjectMap; -typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap; - -typedef std::fbx_unordered_multimap<uint64_t, const Connection*> ConnectionMap; - -/** DOM class for global document settings, a single instance per document can - * be accessed via Document.Globals(). */ -class FileGlobalSettings { -public: - FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props); - - ~FileGlobalSettings(); - - const PropertyTable& Props() const { - ai_assert(props.get()); - return *props.get(); - } - - const Document& GetDocument() const { - return doc; - } - - fbx_simple_property(UpAxis, int, 1) - fbx_simple_property(UpAxisSign, int, 1) - fbx_simple_property(FrontAxis, int, 2) - fbx_simple_property(FrontAxisSign, int, 1) - fbx_simple_property(CoordAxis, int, 0) - fbx_simple_property(CoordAxisSign, int, 1) - fbx_simple_property(OriginalUpAxis, int, 0) - fbx_simple_property(OriginalUpAxisSign, int, 1) - fbx_simple_property(UnitScaleFactor, float, 1) - fbx_simple_property(OriginalUnitScaleFactor, float, 1) - fbx_simple_property(AmbientColor, aiVector3D, aiVector3D(0,0,0)) - fbx_simple_property(DefaultCamera, std::string, "") - - - enum FrameRate { - FrameRate_DEFAULT = 0, - FrameRate_120 = 1, - FrameRate_100 = 2, - FrameRate_60 = 3, - FrameRate_50 = 4, - FrameRate_48 = 5, - FrameRate_30 = 6, - FrameRate_30_DROP = 7, - FrameRate_NTSC_DROP_FRAME = 8, - FrameRate_NTSC_FULL_FRAME = 9, - FrameRate_PAL = 10, - FrameRate_CINEMA = 11, - FrameRate_1000 = 12, - FrameRate_CINEMA_ND = 13, - FrameRate_CUSTOM = 14, - - FrameRate_MAX// end-of-enum sentinel - }; - - fbx_simple_enum_property(TimeMode, FrameRate, FrameRate_DEFAULT) - fbx_simple_property(TimeSpanStart, uint64_t, 0L) - fbx_simple_property(TimeSpanStop, uint64_t, 0L) - fbx_simple_property(CustomFrameRate, float, -1.0f) - -private: - std::shared_ptr<const PropertyTable> props; - const Document& doc; -}; - -/** DOM root for a FBX file */ -class Document { -public: - Document(const Parser& parser, const ImportSettings& settings); - - ~Document(); - - LazyObject* GetObject(uint64_t id) const; - - bool IsBinary() const { - return parser.IsBinary(); - } - - unsigned int FBXVersion() const { - return fbxVersion; - } - - const std::string& Creator() const { - return creator; - } - - // elements (in this order): Year, Month, Day, Hour, Second, Millisecond - const unsigned int* CreationTimeStamp() const { - return creationTimeStamp; - } - - const FileGlobalSettings& GlobalSettings() const { - ai_assert(globals.get()); - return *globals.get(); - } - - const PropertyTemplateMap& Templates() const { - return templates; - } - - const ObjectMap& Objects() const { - return objects; - } - - const ImportSettings& Settings() const { - return settings; - } - - const ConnectionMap& ConnectionsBySource() const { - return src_connections; - } - - const ConnectionMap& ConnectionsByDestination() const { - return dest_connections; - } - - // note: the implicit rule in all DOM classes is to always resolve - // from destination to source (since the FBX object hierarchy is, - // with very few exceptions, a DAG, this avoids cycles). In all - // cases that may involve back-facing edges in the object graph, - // use LazyObject::IsBeingConstructed() to check. - - std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source) const; - std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest) const; - - std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, const char* classname) const; - std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, const char* classname) const; - - std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, - const char* const* classnames, size_t count) const; - std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, - const char* const* classnames, - size_t count) const; - - const std::vector<const AnimationStack*>& AnimationStacks() const; - -private: - std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, const ConnectionMap&) const; - std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, bool is_src, - const ConnectionMap&, - const char* const* classnames, - size_t count) const; - void ReadHeader(); - void ReadObjects(); - void ReadPropertyTemplates(); - void ReadConnections(); - void ReadGlobalSettings(); - -private: - const ImportSettings& settings; - - ObjectMap objects; - const Parser& parser; - - PropertyTemplateMap templates; - ConnectionMap src_connections; - ConnectionMap dest_connections; - - unsigned int fbxVersion; - std::string creator; - unsigned int creationTimeStamp[7]; - - std::vector<uint64_t> animationStacks; - mutable std::vector<const AnimationStack*> animationStacksResolved; - - std::unique_ptr<FileGlobalSettings> globals; -}; - -} // Namespace FBX -} // Namespace Assimp - -namespace std -{ - template <> - struct hash<const Assimp::FBX::Video> - { - std::size_t operator()(const Assimp::FBX::Video& video) const - { - using std::size_t; - using std::hash; - using std::string; - - size_t res = 17; - res = res * 31 + hash<string>()(video.Name()); - res = res * 31 + hash<string>()(video.RelativeFilename()); - res = res * 31 + hash<string>()(video.Type()); - - return res; - } - }; -} - -#endif // INCLUDED_AI_FBX_DOCUMENT_H diff --git a/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp b/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp deleted file mode 100644 index f84691479a..0000000000 --- a/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXDocumentUtil.cpp - * @brief Implementation of the FBX DOM utility functions declared in FBXDocumentUtil.h - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXParser.h" -#include "FBXDocument.h" -#include "FBXUtil.h" -#include "FBXDocumentUtil.h" -#include "FBXProperties.h" - - -namespace Assimp { -namespace FBX { -namespace Util { - -// ------------------------------------------------------------------------------------------------ -// signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError. -void DOMError(const std::string& message, const Token& token) -{ - throw DeadlyImportError(Util::AddTokenText("FBX-DOM",message,&token)); -} - -// ------------------------------------------------------------------------------------------------ -void DOMError(const std::string& message, const Element* element /*= NULL*/) -{ - if(element) { - DOMError(message,element->KeyToken()); - } - throw DeadlyImportError("FBX-DOM " + message); -} - - -// ------------------------------------------------------------------------------------------------ -// print warning, do return -void DOMWarning(const std::string& message, const Token& token) -{ - if(DefaultLogger::get()) { - ASSIMP_LOG_WARN(Util::AddTokenText("FBX-DOM",message,&token)); - } -} - -// ------------------------------------------------------------------------------------------------ -void DOMWarning(const std::string& message, const Element* element /*= NULL*/) -{ - if(element) { - DOMWarning(message,element->KeyToken()); - return; - } - if(DefaultLogger::get()) { - ASSIMP_LOG_WARN("FBX-DOM: " + message); - } -} - - -// ------------------------------------------------------------------------------------------------ -// fetch a property table and the corresponding property template -std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc, - const std::string& templateName, - const Element &element, - const Scope& sc, - bool no_warn /*= false*/) -{ - const Element* const Properties70 = sc["Properties70"]; - std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>( - static_cast<const PropertyTable*>(NULL)); - - if(templateName.length()) { - PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName); - if(it != doc.Templates().end()) { - templateProps = (*it).second; - } - } - - if(!Properties70 || !Properties70->Compound()) { - if(!no_warn) { - DOMWarning("property table (Properties70) not found",&element); - } - if(templateProps) { - return templateProps; - } - else { - return std::make_shared<const PropertyTable>(); - } - } - return std::make_shared<const PropertyTable>(*Properties70,templateProps); -} -} // !Util -} // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXDocumentUtil.h b/thirdparty/assimp/code/FBX/FBXDocumentUtil.h deleted file mode 100644 index 2450109e59..0000000000 --- a/thirdparty/assimp/code/FBX/FBXDocumentUtil.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXDocumentUtil.h - * @brief FBX internal utilities used by the DOM reading code - */ -#ifndef INCLUDED_AI_FBX_DOCUMENT_UTIL_H -#define INCLUDED_AI_FBX_DOCUMENT_UTIL_H - -#include <assimp/defs.h> -#include <string> -#include <memory> -#include "FBXDocument.h" - -struct Token; -struct Element; - -namespace Assimp { -namespace FBX { -namespace Util { - -/* DOM/Parse error reporting - does not return */ -AI_WONT_RETURN void DOMError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX; -AI_WONT_RETURN void DOMError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX; - -// does return -void DOMWarning(const std::string& message, const Token& token); -void DOMWarning(const std::string& message, const Element* element = NULL); - - -// fetch a property table and the corresponding property template -std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc, - const std::string& templateName, - const Element &element, - const Scope& sc, - bool no_warn = false); - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -const T* ProcessSimpleConnection(const Connection& con, - bool is_object_property_conn, - const char* name, - const Element& element, - const char** propNameOut = nullptr) -{ - if (is_object_property_conn && !con.PropertyName().length()) { - DOMWarning("expected incoming " + std::string(name) + - " link to be an object-object connection, ignoring", - &element - ); - return nullptr; - } - else if (!is_object_property_conn && con.PropertyName().length()) { - DOMWarning("expected incoming " + std::string(name) + - " link to be an object-property connection, ignoring", - &element - ); - return nullptr; - } - - if(is_object_property_conn && propNameOut) { - // note: this is ok, the return value of PropertyValue() is guaranteed to - // remain valid and unchanged as long as the document exists. - *propNameOut = con.PropertyName().c_str(); - } - - const Object* const ob = con.SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for incoming " + std::string(name) + - " link, ignoring", - &element); - return nullptr; - } - - return dynamic_cast<const T*>(ob); -} - -} //!Util -} //!FBX -} //!Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXExportNode.cpp b/thirdparty/assimp/code/FBX/FBXExportNode.cpp deleted file mode 100644 index 06c89cee46..0000000000 --- a/thirdparty/assimp/code/FBX/FBXExportNode.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#ifndef ASSIMP_BUILD_NO_EXPORT -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -#include "FBXExportNode.h" -#include "FBXCommon.h" - -#include <assimp/StreamWriter.h> // StreamWriterLE -#include <assimp/Exceptional.h> // DeadlyExportError -#include <assimp/ai_assert.h> -#include <assimp/StringUtils.h> // ai_snprintf - -#include <string> -#include <ostream> -#include <sstream> // ostringstream -#include <memory> // shared_ptr - -namespace Assimp { -// AddP70<type> helpers... there's no usable pattern here, -// so all are defined as separate functions. -// Even "animatable" properties are often completely different -// from the standard (nonanimated) property definition, -// so they are specified with an 'A' suffix. - -void FBX::Node::AddP70int( - const std::string& name, int32_t value -) { - FBX::Node n("P"); - n.AddProperties(name, "int", "Integer", "", value); - AddChild(n); -} - -void FBX::Node::AddP70bool( - const std::string& name, bool value -) { - FBX::Node n("P"); - n.AddProperties(name, "bool", "", "", int32_t(value)); - AddChild(n); -} - -void FBX::Node::AddP70double( - const std::string& name, double value -) { - FBX::Node n("P"); - n.AddProperties(name, "double", "Number", "", value); - AddChild(n); -} - -void FBX::Node::AddP70numberA( - const std::string& name, double value -) { - FBX::Node n("P"); - n.AddProperties(name, "Number", "", "A", value); - AddChild(n); -} - -void FBX::Node::AddP70color( - const std::string& name, double r, double g, double b -) { - FBX::Node n("P"); - n.AddProperties(name, "ColorRGB", "Color", "", r, g, b); - AddChild(n); -} - -void FBX::Node::AddP70colorA( - const std::string& name, double r, double g, double b -) { - FBX::Node n("P"); - n.AddProperties(name, "Color", "", "A", r, g, b); - AddChild(n); -} - -void FBX::Node::AddP70vector( - const std::string& name, double x, double y, double z -) { - FBX::Node n("P"); - n.AddProperties(name, "Vector3D", "Vector", "", x, y, z); - AddChild(n); -} - -void FBX::Node::AddP70vectorA( - const std::string& name, double x, double y, double z -) { - FBX::Node n("P"); - n.AddProperties(name, "Vector", "", "A", x, y, z); - AddChild(n); -} - -void FBX::Node::AddP70string( - const std::string& name, const std::string& value -) { - FBX::Node n("P"); - n.AddProperties(name, "KString", "", "", value); - AddChild(n); -} - -void FBX::Node::AddP70enum( - const std::string& name, int32_t value -) { - FBX::Node n("P"); - n.AddProperties(name, "enum", "", "", value); - AddChild(n); -} - -void FBX::Node::AddP70time( - const std::string& name, int64_t value -) { - FBX::Node n("P"); - n.AddProperties(name, "KTime", "Time", "", value); - AddChild(n); -} - - -// public member functions for writing nodes to stream - -void FBX::Node::Dump( - std::shared_ptr<Assimp::IOStream> outfile, - bool binary, int indent -) { - if (binary) { - Assimp::StreamWriterLE outstream(outfile); - DumpBinary(outstream); - } else { - std::ostringstream ss; - DumpAscii(ss, indent); - std::string s = ss.str(); - outfile->Write(s.c_str(), s.size(), 1); - } -} - -void FBX::Node::Dump( - Assimp::StreamWriterLE &outstream, - bool binary, int indent -) { - if (binary) { - DumpBinary(outstream); - } else { - std::ostringstream ss; - DumpAscii(ss, indent); - outstream.PutString(ss.str()); - } -} - - -// public member functions for low-level writing - -void FBX::Node::Begin( - Assimp::StreamWriterLE &s, - bool binary, int indent -) { - if (binary) { - BeginBinary(s); - } else { - // assume we're at the correct place to start already - (void)indent; - std::ostringstream ss; - BeginAscii(ss, indent); - s.PutString(ss.str()); - } -} - -void FBX::Node::DumpProperties( - Assimp::StreamWriterLE& s, - bool binary, int indent -) { - if (binary) { - DumpPropertiesBinary(s); - } else { - std::ostringstream ss; - DumpPropertiesAscii(ss, indent); - s.PutString(ss.str()); - } -} - -void FBX::Node::EndProperties( - Assimp::StreamWriterLE &s, - bool binary, int indent -) { - EndProperties(s, binary, indent, properties.size()); -} - -void FBX::Node::EndProperties( - Assimp::StreamWriterLE &s, - bool binary, int indent, - size_t num_properties -) { - if (binary) { - EndPropertiesBinary(s, num_properties); - } else { - // nothing to do - (void)indent; - } -} - -void FBX::Node::BeginChildren( - Assimp::StreamWriterLE &s, - bool binary, int indent -) { - if (binary) { - // nothing to do - } else { - std::ostringstream ss; - BeginChildrenAscii(ss, indent); - s.PutString(ss.str()); - } -} - -void FBX::Node::DumpChildren( - Assimp::StreamWriterLE& s, - bool binary, int indent -) { - if (binary) { - DumpChildrenBinary(s); - } else { - std::ostringstream ss; - DumpChildrenAscii(ss, indent); - if (ss.tellp() > 0) - s.PutString(ss.str()); - } -} - -void FBX::Node::End( - Assimp::StreamWriterLE &s, - bool binary, int indent, - bool has_children -) { - if (binary) { - EndBinary(s, has_children); - } else { - std::ostringstream ss; - EndAscii(ss, indent, has_children); - if (ss.tellp() > 0) - s.PutString(ss.str()); - } -} - - -// public member functions for writing to binary fbx - -void FBX::Node::DumpBinary(Assimp::StreamWriterLE &s) -{ - // write header section (with placeholders for some things) - BeginBinary(s); - - // write properties - DumpPropertiesBinary(s); - - // go back and fill in property related placeholders - EndPropertiesBinary(s, properties.size()); - - // write children - DumpChildrenBinary(s); - - // finish, filling in end offset placeholder - EndBinary(s, force_has_children || !children.empty()); -} - - -// public member functions for writing to ascii fbx - -void FBX::Node::DumpAscii(std::ostream &s, int indent) -{ - // write name - BeginAscii(s, indent); - - // write properties - DumpPropertiesAscii(s, indent); - - if (force_has_children || !children.empty()) { - // begin children (with a '{') - BeginChildrenAscii(s, indent + 1); - // write children - DumpChildrenAscii(s, indent + 1); - } - - // finish (also closing the children bracket '}') - EndAscii(s, indent, force_has_children || !children.empty()); -} - - -// private member functions for low-level writing to fbx - -void FBX::Node::BeginBinary(Assimp::StreamWriterLE &s) -{ - // remember start pos so we can come back and write the end pos - this->start_pos = s.Tell(); - - // placeholders for end pos and property section info - s.PutU4(0); // end pos - s.PutU4(0); // number of properties - s.PutU4(0); // total property section length - - // node name - s.PutU1(uint8_t(name.size())); // length of node name - s.PutString(name); // node name as raw bytes - - // property data comes after here - this->property_start = s.Tell(); -} - -void FBX::Node::DumpPropertiesBinary(Assimp::StreamWriterLE& s) -{ - for (auto &p : properties) { - p.DumpBinary(s); - } -} - -void FBX::Node::EndPropertiesBinary( - Assimp::StreamWriterLE &s, - size_t num_properties -) { - if (num_properties == 0) { return; } - size_t pos = s.Tell(); - ai_assert(pos > property_start); - size_t property_section_size = pos - property_start; - s.Seek(start_pos + 4); - s.PutU4(uint32_t(num_properties)); - s.PutU4(uint32_t(property_section_size)); - s.Seek(pos); -} - -void FBX::Node::DumpChildrenBinary(Assimp::StreamWriterLE& s) -{ - for (FBX::Node& child : children) { - child.DumpBinary(s); - } -} - -void FBX::Node::EndBinary( - Assimp::StreamWriterLE &s, - bool has_children -) { - // if there were children, add a null record - if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD); } - - // now go back and write initial pos - this->end_pos = s.Tell(); - s.Seek(start_pos); - s.PutU4(uint32_t(end_pos)); - s.Seek(end_pos); -} - - -void FBX::Node::BeginAscii(std::ostream& s, int indent) -{ - s << '\n'; - for (int i = 0; i < indent; ++i) { s << '\t'; } - s << name << ": "; -} - -void FBX::Node::DumpPropertiesAscii(std::ostream &s, int indent) -{ - for (size_t i = 0; i < properties.size(); ++i) { - if (i > 0) { s << ", "; } - properties[i].DumpAscii(s, indent); - } -} - -void FBX::Node::BeginChildrenAscii(std::ostream& s, int indent) -{ - // only call this if there are actually children - s << " {"; - (void)indent; -} - -void FBX::Node::DumpChildrenAscii(std::ostream& s, int indent) -{ - // children will need a lot of padding and corralling - if (children.size() || force_has_children) { - for (size_t i = 0; i < children.size(); ++i) { - // no compression in ascii files, so skip this node if it exists - if (children[i].name == "EncryptionType") { continue; } - // the child can dump itself - children[i].DumpAscii(s, indent); - } - } -} - -void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children) -{ - if (!has_children) { return; } // nothing to do - s << '\n'; - for (int i = 0; i < indent; ++i) { s << '\t'; } - s << "}"; -} - -// private helpers for static member functions - -// ascii property node from vector of doubles -void FBX::Node::WritePropertyNodeAscii( - const std::string& name, - const std::vector<double>& v, - Assimp::StreamWriterLE& s, - int indent -){ - char buffer[32]; - FBX::Node node(name); - node.Begin(s, false, indent); - std::string vsize = to_string(v.size()); - // *<size> { - s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n"); - // indent + 1 - for (int i = 0; i < indent + 1; ++i) { s.PutChar('\t'); } - // a: value,value,value,... - s.PutString("a: "); - int count = 0; - for (size_t i = 0; i < v.size(); ++i) { - if (i > 0) { s.PutChar(','); } - int len = ai_snprintf(buffer, sizeof(buffer), "%f", v[i]); - count += len; - if (count > 2048) { s.PutChar('\n'); count = 0; } - if (len < 0 || len > 31) { - // this should never happen - throw DeadlyExportError("failed to convert double to string"); - } - for (int j = 0; j < len; ++j) { s.PutChar(buffer[j]); } - } - // } - s.PutChar('\n'); - for (int i = 0; i < indent; ++i) { s.PutChar('\t'); } - s.PutChar('}'); s.PutChar(' '); - node.End(s, false, indent, false); -} - -// ascii property node from vector of int32_t -void FBX::Node::WritePropertyNodeAscii( - const std::string& name, - const std::vector<int32_t>& v, - Assimp::StreamWriterLE& s, - int indent -){ - char buffer[32]; - FBX::Node node(name); - node.Begin(s, false, indent); - std::string vsize = to_string(v.size()); - // *<size> { - s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n"); - // indent + 1 - for (int i = 0; i < indent + 1; ++i) { s.PutChar('\t'); } - // a: value,value,value,... - s.PutString("a: "); - int count = 0; - for (size_t i = 0; i < v.size(); ++i) { - if (i > 0) { s.PutChar(','); } - int len = ai_snprintf(buffer, sizeof(buffer), "%d", v[i]); - count += len; - if (count > 2048) { s.PutChar('\n'); count = 0; } - if (len < 0 || len > 31) { - // this should never happen - throw DeadlyExportError("failed to convert double to string"); - } - for (int j = 0; j < len; ++j) { s.PutChar(buffer[j]); } - } - // } - s.PutChar('\n'); - for (int i = 0; i < indent; ++i) { s.PutChar('\t'); } - s.PutChar('}'); s.PutChar(' '); - node.End(s, false, indent, false); -} - -// binary property node from vector of doubles -// TODO: optional zip compression! -void FBX::Node::WritePropertyNodeBinary( - const std::string& name, - const std::vector<double>& v, - Assimp::StreamWriterLE& s -){ - FBX::Node node(name); - node.BeginBinary(s); - s.PutU1('d'); - s.PutU4(uint32_t(v.size())); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - s.PutU4(uint32_t(v.size()) * 8); // data size - for (auto it = v.begin(); it != v.end(); ++it) { s.PutF8(*it); } - node.EndPropertiesBinary(s, 1); - node.EndBinary(s, false); -} - -// binary property node from vector of int32_t -// TODO: optional zip compression! -void FBX::Node::WritePropertyNodeBinary( - const std::string& name, - const std::vector<int32_t>& v, - Assimp::StreamWriterLE& s -){ - FBX::Node node(name); - node.BeginBinary(s); - s.PutU1('i'); - s.PutU4(uint32_t(v.size())); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - s.PutU4(uint32_t(v.size()) * 4); // data size - for (auto it = v.begin(); it != v.end(); ++it) { s.PutI4(*it); } - node.EndPropertiesBinary(s, 1); - node.EndBinary(s, false); -} - -// public static member functions - -// convenience function to create and write a property node, -// holding a single property which is an array of values. -// does not copy the data, so is efficient for large arrays. -void FBX::Node::WritePropertyNode( - const std::string& name, - const std::vector<double>& v, - Assimp::StreamWriterLE& s, - bool binary, int indent -){ - if (binary) { - FBX::Node::WritePropertyNodeBinary(name, v, s); - } else { - FBX::Node::WritePropertyNodeAscii(name, v, s, indent); - } -} - -// convenience function to create and write a property node, -// holding a single property which is an array of values. -// does not copy the data, so is efficient for large arrays. -void FBX::Node::WritePropertyNode( - const std::string& name, - const std::vector<int32_t>& v, - Assimp::StreamWriterLE& s, - bool binary, int indent -){ - if (binary) { - FBX::Node::WritePropertyNodeBinary(name, v, s); - } else { - FBX::Node::WritePropertyNodeAscii(name, v, s, indent); - } -} -} -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER -#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/thirdparty/assimp/code/FBX/FBXExportNode.h b/thirdparty/assimp/code/FBX/FBXExportNode.h deleted file mode 100644 index ef3bc781a4..0000000000 --- a/thirdparty/assimp/code/FBX/FBXExportNode.h +++ /dev/null @@ -1,271 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXExportNode.h -* Declares the FBX::Node helper class for fbx export. -*/ -#ifndef AI_FBXEXPORTNODE_H_INC -#define AI_FBXEXPORTNODE_H_INC - -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -#include "FBXExportProperty.h" - -#include <assimp/StreamWriter.h> // StreamWriterLE - -#include <string> -#include <vector> - -namespace Assimp { -namespace FBX { - class Node; -} - -class FBX::Node { -public: - // TODO: accessors - std::string name; // node name - std::vector<FBX::FBXExportProperty> properties; // node properties - std::vector<FBX::Node> children; // child nodes - - // some nodes always pretend they have children... - bool force_has_children = false; - -public: // constructors - /// The default class constructor. - Node() = default; - - /// The class constructor with the name. - Node(const std::string& n) - : name(n) - , properties() - , children() - , force_has_children( false ) { - // empty - } - - // convenience template to construct with properties directly - template <typename... More> - Node(const std::string& n, const More... more) - : name(n) - , properties() - , children() - , force_has_children(false) { - AddProperties(more...); - } - -public: // functions to add properties or children - // add a single property to the node - template <typename T> - void AddProperty(T value) { - properties.emplace_back(value); - } - - // convenience function to add multiple properties at once - template <typename T, typename... More> - void AddProperties(T value, More... more) { - properties.emplace_back(value); - AddProperties(more...); - } - void AddProperties() {} - - // add a child node directly - void AddChild(const Node& node) { children.push_back(node); } - - // convenience function to add a child node with a single property - template <typename... More> - void AddChild( - const std::string& name, - More... more - ) { - FBX::Node c(name); - c.AddProperties(more...); - children.push_back(c); - } - -public: // support specifically for dealing with Properties70 nodes - - // it really is simpler to make these all separate functions. - // the versions with 'A' suffixes are for animatable properties. - // those often follow a completely different format internally in FBX. - void AddP70int(const std::string& name, int32_t value); - void AddP70bool(const std::string& name, bool value); - void AddP70double(const std::string& name, double value); - void AddP70numberA(const std::string& name, double value); - void AddP70color(const std::string& name, double r, double g, double b); - void AddP70colorA(const std::string& name, double r, double g, double b); - void AddP70vector(const std::string& name, double x, double y, double z); - void AddP70vectorA(const std::string& name, double x, double y, double z); - void AddP70string(const std::string& name, const std::string& value); - void AddP70enum(const std::string& name, int32_t value); - void AddP70time(const std::string& name, int64_t value); - - // template for custom P70 nodes. - // anything that doesn't fit in the above can be created manually. - template <typename... More> - void AddP70( - const std::string& name, - const std::string& type, - const std::string& type2, - const std::string& flags, - More... more - ) { - Node n("P"); - n.AddProperties(name, type, type2, flags, more...); - AddChild(n); - } - -public: // member functions for writing data to a file or stream - - // write the full node to the given file or stream - void Dump( - std::shared_ptr<Assimp::IOStream> outfile, - bool binary, int indent - ); - void Dump(Assimp::StreamWriterLE &s, bool binary, int indent); - - // these other functions are for writing data piece by piece. - // they must be used carefully. - // for usage examples see FBXExporter.cpp. - void Begin(Assimp::StreamWriterLE &s, bool binary, int indent); - void DumpProperties(Assimp::StreamWriterLE& s, bool binary, int indent); - void EndProperties(Assimp::StreamWriterLE &s, bool binary, int indent); - void EndProperties( - Assimp::StreamWriterLE &s, bool binary, int indent, - size_t num_properties - ); - void BeginChildren(Assimp::StreamWriterLE &s, bool binary, int indent); - void DumpChildren(Assimp::StreamWriterLE& s, bool binary, int indent); - void End( - Assimp::StreamWriterLE &s, bool binary, int indent, - bool has_children - ); - -private: // internal functions used for writing - - void DumpBinary(Assimp::StreamWriterLE &s); - void DumpAscii(Assimp::StreamWriterLE &s, int indent); - void DumpAscii(std::ostream &s, int indent); - - void BeginBinary(Assimp::StreamWriterLE &s); - void DumpPropertiesBinary(Assimp::StreamWriterLE& s); - void EndPropertiesBinary(Assimp::StreamWriterLE &s); - void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties); - void DumpChildrenBinary(Assimp::StreamWriterLE& s); - void EndBinary(Assimp::StreamWriterLE &s, bool has_children); - - void BeginAscii(std::ostream &s, int indent); - void DumpPropertiesAscii(std::ostream &s, int indent); - void BeginChildrenAscii(std::ostream &s, int indent); - void DumpChildrenAscii(std::ostream &s, int indent); - void EndAscii(std::ostream &s, int indent, bool has_children); - -private: // data used for binary dumps - size_t start_pos; // starting position in stream - size_t end_pos; // ending position in stream - size_t property_start; // starting position of property section - -public: // static member functions - - // convenience function to create a node with a single property, - // and write it to the stream. - template <typename T> - static void WritePropertyNode( - const std::string& name, - const T value, - Assimp::StreamWriterLE& s, - bool binary, int indent - ) { - FBX::FBXExportProperty p(value); - FBX::Node node(name, p); - node.Dump(s, binary, indent); - } - - // convenience function to create and write a property node, - // holding a single property which is an array of values. - // does not copy the data, so is efficient for large arrays. - static void WritePropertyNode( - const std::string& name, - const std::vector<double>& v, - Assimp::StreamWriterLE& s, - bool binary, int indent - ); - - // convenience function to create and write a property node, - // holding a single property which is an array of values. - // does not copy the data, so is efficient for large arrays. - static void WritePropertyNode( - const std::string& name, - const std::vector<int32_t>& v, - Assimp::StreamWriterLE& s, - bool binary, int indent - ); - -private: // static helper functions - static void WritePropertyNodeAscii( - const std::string& name, - const std::vector<double>& v, - Assimp::StreamWriterLE& s, - int indent - ); - static void WritePropertyNodeAscii( - const std::string& name, - const std::vector<int32_t>& v, - Assimp::StreamWriterLE& s, - int indent - ); - static void WritePropertyNodeBinary( - const std::string& name, - const std::vector<double>& v, - Assimp::StreamWriterLE& s - ); - static void WritePropertyNodeBinary( - const std::string& name, - const std::vector<int32_t>& v, - Assimp::StreamWriterLE& s - ); - -}; -} - -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER - -#endif // AI_FBXEXPORTNODE_H_INC diff --git a/thirdparty/assimp/code/FBX/FBXExportProperty.cpp b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp deleted file mode 100644 index f2a63b72b9..0000000000 --- a/thirdparty/assimp/code/FBX/FBXExportProperty.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#ifndef ASSIMP_BUILD_NO_EXPORT -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -#include "FBXExportProperty.h" - -#include <assimp/StreamWriter.h> // StreamWriterLE -#include <assimp/Exceptional.h> // DeadlyExportError - -#include <string> -#include <vector> -#include <ostream> -#include <locale> -#include <sstream> // ostringstream - -namespace Assimp { -namespace FBX { - -// constructors for single element properties - -FBXExportProperty::FBXExportProperty(bool v) -: type('C') -, data(1, uint8_t(v)) {} - -FBXExportProperty::FBXExportProperty(int16_t v) -: type('Y') -, data(2) { - uint8_t* d = data.data(); - (reinterpret_cast<int16_t*>(d))[0] = v; -} - -FBXExportProperty::FBXExportProperty(int32_t v) -: type('I') -, data(4) { - uint8_t* d = data.data(); - (reinterpret_cast<int32_t*>(d))[0] = v; -} - -FBXExportProperty::FBXExportProperty(float v) -: type('F') -, data(4) { - uint8_t* d = data.data(); - (reinterpret_cast<float*>(d))[0] = v; -} - -FBXExportProperty::FBXExportProperty(double v) -: type('D') -, data(8) { - uint8_t* d = data.data(); - (reinterpret_cast<double*>(d))[0] = v; -} - -FBXExportProperty::FBXExportProperty(int64_t v) -: type('L') -, data(8) { - uint8_t* d = data.data(); - (reinterpret_cast<int64_t*>(d))[0] = v; -} - -// constructors for array-type properties - -FBXExportProperty::FBXExportProperty(const char* c, bool raw) -: FBXExportProperty(std::string(c), raw) { - // empty -} - -// strings can either be saved as "raw" (R) data, or "string" (S) data -FBXExportProperty::FBXExportProperty(const std::string& s, bool raw) -: type(raw ? 'R' : 'S') -, data(s.size()) { - for (size_t i = 0; i < s.size(); ++i) { - data[i] = uint8_t(s[i]); - } -} - -FBXExportProperty::FBXExportProperty(const std::vector<uint8_t>& r) -: type('R') -, data(r) { - // empty -} - -FBXExportProperty::FBXExportProperty(const std::vector<int32_t>& va) -: type('i') -, data(4 * va.size() ) { - int32_t* d = reinterpret_cast<int32_t*>(data.data()); - for (size_t i = 0; i < va.size(); ++i) { - d[i] = va[i]; - } -} - -FBXExportProperty::FBXExportProperty(const std::vector<int64_t>& va) -: type('l') -, data(8 * va.size()) { - int64_t* d = reinterpret_cast<int64_t*>(data.data()); - for (size_t i = 0; i < va.size(); ++i) { - d[i] = va[i]; - } -} - -FBXExportProperty::FBXExportProperty(const std::vector<float>& va) -: type('f') -, data(4 * va.size()) { - float* d = reinterpret_cast<float*>(data.data()); - for (size_t i = 0; i < va.size(); ++i) { - d[i] = va[i]; - } -} - -FBXExportProperty::FBXExportProperty(const std::vector<double>& va) -: type('d') -, data(8 * va.size()) { - double* d = reinterpret_cast<double*>(data.data()); - for (size_t i = 0; i < va.size(); ++i) { - d[i] = va[i]; - } -} - -FBXExportProperty::FBXExportProperty(const aiMatrix4x4& vm) -: type('d') -, data(8 * 16) { - double* d = reinterpret_cast<double*>(data.data()); - for (unsigned int c = 0; c < 4; ++c) { - for (unsigned int r = 0; r < 4; ++r) { - d[4 * c + r] = vm[r][c]; - } - } -} - -// public member functions - -size_t FBXExportProperty::size() { - switch (type) { - case 'C': - case 'Y': - case 'I': - case 'F': - case 'D': - case 'L': - return data.size() + 1; - case 'S': - case 'R': - return data.size() + 5; - case 'i': - case 'd': - return data.size() + 13; - default: - throw DeadlyExportError("Requested size on property of unknown type"); - } -} - -void FBXExportProperty::DumpBinary(Assimp::StreamWriterLE& s) { - s.PutU1(type); - uint8_t* d = data.data(); - size_t N; - switch (type) { - case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return; - case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return; - case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return; - case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return; - case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return; - case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return; - case 'S': - case 'R': - s.PutU4(uint32_t(data.size())); - for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); } - return; - case 'i': - N = data.size() / 4; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutI4((reinterpret_cast<int32_t*>(d))[i]); - } - return; - case 'l': - N = data.size() / 8; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutI8((reinterpret_cast<int64_t*>(d))[i]); - } - return; - case 'f': - N = data.size() / 4; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutF4((reinterpret_cast<float*>(d))[i]); - } - return; - case 'd': - N = data.size() / 8; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutF8((reinterpret_cast<double*>(d))[i]); - } - return; - default: - std::ostringstream err; - err << "Tried to dump property with invalid type '"; - err << type << "'!"; - throw DeadlyExportError(err.str()); - } -} - -void FBXExportProperty::DumpAscii(Assimp::StreamWriterLE& outstream, int indent) { - std::ostringstream ss; - ss.imbue(std::locale::classic()); - ss.precision(15); // this seems to match official FBX SDK exports - DumpAscii(ss, indent); - outstream.PutString(ss.str()); -} - -void FBXExportProperty::DumpAscii(std::ostream& s, int indent) { - // no writing type... or anything. just shove it into the stream. - uint8_t* d = data.data(); - size_t N; - size_t swap = data.size(); - size_t count = 0; - switch (type) { - case 'C': - if (*(reinterpret_cast<uint8_t*>(d))) { s << 'T'; } - else { s << 'F'; } - return; - case 'Y': s << *(reinterpret_cast<int16_t*>(d)); return; - case 'I': s << *(reinterpret_cast<int32_t*>(d)); return; - case 'F': s << *(reinterpret_cast<float*>(d)); return; - case 'D': s << *(reinterpret_cast<double*>(d)); return; - case 'L': s << *(reinterpret_cast<int64_t*>(d)); return; - case 'S': - // first search to see if it has "\x00\x01" in it - - // which separates fields which are reversed in the ascii version. - // yeah. - // FBX, yeah. - for (size_t i = 0; i < data.size(); ++i) { - if (data[i] == '\0') { - swap = i; - break; - } - } - case 'R': - s << '"'; - // we might as well check this now, - // probably it will never happen - for (size_t i = 0; i < data.size(); ++i) { - char c = data[i]; - if (c == '"') { - throw runtime_error("can't handle quotes in property string"); - } - } - // first write the SWAPPED member (if any) - for (size_t i = swap + 2; i < data.size(); ++i) { - char c = data[i]; - s << c; - } - // then a separator - if (swap != data.size()) { - s << "::"; - } - // then the initial member - for (size_t i = 0; i < swap; ++i) { - char c = data[i]; - s << c; - } - s << '"'; - return; - case 'i': - N = data.size() / 4; // number of elements - s << '*' << N << " {\n"; - for (int i = 0; i < indent + 1; ++i) { s << '\t'; } - s << "a: "; - for (size_t i = 0; i < N; ++i) { - if (i > 0) { s << ','; } - if (count++ > 120) { s << '\n'; count = 0; } - s << (reinterpret_cast<int32_t*>(d))[i]; - } - s << '\n'; - for (int i = 0; i < indent; ++i) { s << '\t'; } - s << "} "; - return; - case 'l': - N = data.size() / 8; - s << '*' << N << " {\n"; - for (int i = 0; i < indent + 1; ++i) { s << '\t'; } - s << "a: "; - for (size_t i = 0; i < N; ++i) { - if (i > 0) { s << ','; } - if (count++ > 120) { s << '\n'; count = 0; } - s << (reinterpret_cast<int64_t*>(d))[i]; - } - s << '\n'; - for (int i = 0; i < indent; ++i) { s << '\t'; } - s << "} "; - return; - case 'f': - N = data.size() / 4; - s << '*' << N << " {\n"; - for (int i = 0; i < indent + 1; ++i) { s << '\t'; } - s << "a: "; - for (size_t i = 0; i < N; ++i) { - if (i > 0) { s << ','; } - if (count++ > 120) { s << '\n'; count = 0; } - s << (reinterpret_cast<float*>(d))[i]; - } - s << '\n'; - for (int i = 0; i < indent; ++i) { s << '\t'; } - s << "} "; - return; - case 'd': - N = data.size() / 8; - s << '*' << N << " {\n"; - for (int i = 0; i < indent + 1; ++i) { s << '\t'; } - s << "a: "; - // set precision to something that can handle doubles - s.precision(15); - for (size_t i = 0; i < N; ++i) { - if (i > 0) { s << ','; } - if (count++ > 120) { s << '\n'; count = 0; } - s << (reinterpret_cast<double*>(d))[i]; - } - s << '\n'; - for (int i = 0; i < indent; ++i) { s << '\t'; } - s << "} "; - return; - default: - std::ostringstream err; - err << "Tried to dump property with invalid type '"; - err << type << "'!"; - throw runtime_error(err.str()); - } -} - -} // Namespace FBX -} // Namespace Assimp - -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER -#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/thirdparty/assimp/code/FBX/FBXExportProperty.h b/thirdparty/assimp/code/FBX/FBXExportProperty.h deleted file mode 100644 index d692fe6ee3..0000000000 --- a/thirdparty/assimp/code/FBX/FBXExportProperty.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXExportProperty.h -* Declares the FBX::Property helper class for fbx export. -*/ -#ifndef AI_FBXEXPORTPROPERTY_H_INC -#define AI_FBXEXPORTPROPERTY_H_INC - -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -#include <assimp/types.h> // aiMatrix4x4 -#include <assimp/StreamWriter.h> // StreamWriterLE - -#include <string> -#include <vector> -#include <ostream> -#include <type_traits> // is_void - -namespace Assimp { -namespace FBX { - -/** @brief FBX::Property - * - * Holds a value of any of FBX's recognized types, - * each represented by a particular one-character code. - * C : 1-byte uint8, usually 0x00 or 0x01 to represent boolean false and true - * Y : 2-byte int16 - * I : 4-byte int32 - * F : 4-byte float - * D : 8-byte double - * L : 8-byte int64 - * i : array of int32 - * f : array of float - * d : array of double - * l : array of int64 - * b : array of 1-byte booleans (0x00 or 0x01) - * S : string (array of 1-byte char) - * R : raw data (array of bytes) - */ -class FBXExportProperty { -public: - // constructors for basic types. - // all explicit to avoid accidental typecasting - explicit FBXExportProperty(bool v); - // TODO: determine if there is actually a byte type, - // or if this always means <bool>. 'C' seems to imply <char>, - // so possibly the above was intended to represent both. - explicit FBXExportProperty(int16_t v); - explicit FBXExportProperty(int32_t v); - explicit FBXExportProperty(float v); - explicit FBXExportProperty(double v); - explicit FBXExportProperty(int64_t v); - // strings can either be stored as 'R' (raw) or 'S' (string) type - explicit FBXExportProperty(const char* c, bool raw = false); - explicit FBXExportProperty(const std::string& s, bool raw = false); - explicit FBXExportProperty(const std::vector<uint8_t>& r); - explicit FBXExportProperty(const std::vector<int32_t>& va); - explicit FBXExportProperty(const std::vector<int64_t>& va); - explicit FBXExportProperty(const std::vector<double>& va); - explicit FBXExportProperty(const std::vector<float>& va); - explicit FBXExportProperty(const aiMatrix4x4& vm); - - // this will catch any type not defined above, - // so that we don't accidentally convert something we don't want. - // for example (const char*) --> (bool)... seriously wtf C++ - template <class T> - explicit FBXExportProperty(T v) : type('X') { - static_assert(std::is_void<T>::value, "TRIED TO CREATE FBX PROPERTY WITH UNSUPPORTED TYPE, CHECK YOUR PROPERTY INSTANTIATION"); - } // note: no line wrap so it appears verbatim on the compiler error - - // the size of this property node in a binary file, in bytes - size_t size(); - - // write this property node as binary data to the given stream - void DumpBinary(Assimp::StreamWriterLE& s); - void DumpAscii(Assimp::StreamWriterLE& s, int indent = 0); - void DumpAscii(std::ostream& s, int indent = 0); - // note: make sure the ostream is in classic "C" locale - -private: - char type; - std::vector<uint8_t> data; -}; - -} // Namespace FBX -} // Namespace Assimp - -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER - -#endif // AI_FBXEXPORTPROPERTY_H_INC diff --git a/thirdparty/assimp/code/FBX/FBXExporter.cpp b/thirdparty/assimp/code/FBX/FBXExporter.cpp deleted file mode 100644 index 9316dc4f02..0000000000 --- a/thirdparty/assimp/code/FBX/FBXExporter.cpp +++ /dev/null @@ -1,2556 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#ifndef ASSIMP_BUILD_NO_EXPORT -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -#include "FBXExporter.h" -#include "FBXExportNode.h" -#include "FBXExportProperty.h" -#include "FBXCommon.h" -#include "FBXUtil.h" - -#include <assimp/version.h> // aiGetVersion -#include <assimp/IOSystem.hpp> -#include <assimp/Exporter.hpp> -#include <assimp/DefaultLogger.hpp> -#include <assimp/StreamWriter.h> // StreamWriterLE -#include <assimp/Exceptional.h> // DeadlyExportError -#include <assimp/material.h> // aiTextureType -#include <assimp/scene.h> -#include <assimp/mesh.h> - -// Header files, standard library. -#include <memory> // shared_ptr -#include <string> -#include <sstream> // stringstream -#include <ctime> // localtime, tm_* -#include <map> -#include <set> -#include <vector> -#include <array> -#include <unordered_set> -#include <numeric> - -// RESOURCES: -// https://code.blender.org/2013/08/fbx-binary-file-format-specification/ -// https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure - -const ai_real DEG = ai_real( 57.29577951308232087679815481 ); // degrees per radian - -using namespace Assimp; -using namespace Assimp::FBX; - -// some constants that we'll use for writing metadata -namespace Assimp { -namespace FBX { - const std::string EXPORT_VERSION_STR = "7.4.0"; - const uint32_t EXPORT_VERSION_INT = 7400; // 7.4 == 2014/2015 - // FBX files have some hashed values that depend on the creation time field, - // but for now we don't actually know how to generate these. - // what we can do is set them to a known-working version. - // this is the data that Blender uses in their FBX export process. - const std::string GENERIC_CTIME = "1970-01-01 10:00:00:000"; - const std::string GENERIC_FILEID = - "\x28\xb3\x2a\xeb\xb6\x24\xcc\xc2\xbf\xc8\xb0\x2a\xa9\x2b\xfc\xf1"; - const std::string GENERIC_FOOTID = - "\xfa\xbc\xab\x09\xd0\xc8\xd4\x66\xb1\x76\xfb\x83\x1c\xf7\x26\x7e"; - const std::string FOOT_MAGIC = - "\xf8\x5a\x8c\x6a\xde\xf5\xd9\x7e\xec\xe9\x0c\xe3\x75\x8f\x29\x0b"; - const std::string COMMENT_UNDERLINE = - ";------------------------------------------------------------------"; -} - - // --------------------------------------------------------------------- - // Worker function for exporting a scene to binary FBX. - // Prototyped and registered in Exporter.cpp - void ExportSceneFBX ( - const char* pFile, - IOSystem* pIOSystem, - const aiScene* pScene, - const ExportProperties* pProperties - ){ - // initialize the exporter - FBXExporter exporter(pScene, pProperties); - - // perform binary export - exporter.ExportBinary(pFile, pIOSystem); - } - - // --------------------------------------------------------------------- - // Worker function for exporting a scene to ASCII FBX. - // Prototyped and registered in Exporter.cpp - void ExportSceneFBXA ( - const char* pFile, - IOSystem* pIOSystem, - const aiScene* pScene, - const ExportProperties* pProperties - - ){ - // initialize the exporter - FBXExporter exporter(pScene, pProperties); - - // perform ascii export - exporter.ExportAscii(pFile, pIOSystem); - } - -} // end of namespace Assimp - -FBXExporter::FBXExporter ( const aiScene* pScene, const ExportProperties* pProperties ) -: binary(false) -, mScene(pScene) -, mProperties(pProperties) -, outfile() -, connections() -, mesh_uids() -, material_uids() -, node_uids() { - // will probably need to determine UIDs, connections, etc here. - // basically anything that needs to be known - // before we start writing sections to the stream. -} - -void FBXExporter::ExportBinary ( - const char* pFile, - IOSystem* pIOSystem -){ - // remember that we're exporting in binary mode - binary = true; - - // we're not currently using these preferences, - // but clang will cry about it if we never touch it. - // TODO: some of these might be relevant to export - (void)mProperties; - - // open the indicated file for writing (in binary mode) - outfile.reset(pIOSystem->Open(pFile,"wb")); - if (!outfile) { - throw DeadlyExportError( - "could not open output .fbx file: " + std::string(pFile) - ); - } - - // first a binary-specific file header - WriteBinaryHeader(); - - // the rest of the file is in node entries. - // we have to serialize each entry before we write to the output, - // as the first thing we write is the byte offset of the _next_ entry. - // Either that or we can skip back to write the offset when we finish. - WriteAllNodes(); - - // finally we have a binary footer to the file - WriteBinaryFooter(); - - // explicitly release file pointer, - // so we don't have to rely on class destruction. - outfile.reset(); -} - -void FBXExporter::ExportAscii ( - const char* pFile, - IOSystem* pIOSystem -){ - // remember that we're exporting in ascii mode - binary = false; - - // open the indicated file for writing in text mode - outfile.reset(pIOSystem->Open(pFile,"wt")); - if (!outfile) { - throw DeadlyExportError( - "could not open output .fbx file: " + std::string(pFile) - ); - } - - // write the ascii header - WriteAsciiHeader(); - - // write all the sections - WriteAllNodes(); - - // make sure the file ends with a newline. - // note: if the file is opened in text mode, - // this should do the right cross-platform thing. - outfile->Write("\n", 1, 1); - - // explicitly release file pointer, - // so we don't have to rely on class destruction. - outfile.reset(); -} - -void FBXExporter::WriteAsciiHeader() -{ - // basically just a comment at the top of the file - std::stringstream head; - head << "; FBX " << EXPORT_VERSION_STR << " project file\n"; - head << "; Created by the Open Asset Import Library (Assimp)\n"; - head << "; http://assimp.org\n"; - head << "; -------------------------------------------------\n"; - const std::string ascii_header = head.str(); - outfile->Write(ascii_header.c_str(), ascii_header.size(), 1); -} - -void FBXExporter::WriteAsciiSectionHeader(const std::string& title) -{ - StreamWriterLE outstream(outfile); - std::stringstream s; - s << "\n\n; " << title << '\n'; - s << FBX::COMMENT_UNDERLINE << "\n"; - outstream.PutString(s.str()); -} - -void FBXExporter::WriteBinaryHeader() -{ - // first a specific sequence of 23 bytes, always the same - const char binary_header[24] = "Kaydara FBX Binary\x20\x20\x00\x1a\x00"; - outfile->Write(binary_header, 1, 23); - - // then FBX version number, "multiplied" by 1000, as little-endian uint32. - // so 7.3 becomes 7300 == 0x841C0000, 7.4 becomes 7400 == 0xE81C0000, etc - { - StreamWriterLE outstream(outfile); - outstream.PutU4(EXPORT_VERSION_INT); - } // StreamWriter destructor writes the data to the file - - // after this the node data starts immediately - // (probably with the FBXHEaderExtension node) -} - -void FBXExporter::WriteBinaryFooter() -{ - outfile->Write(NULL_RECORD.c_str(), NULL_RECORD.size(), 1); - - outfile->Write(GENERIC_FOOTID.c_str(), GENERIC_FOOTID.size(), 1); - - // here some padding is added for alignment to 16 bytes. - // if already aligned, the full 16 bytes is added. - size_t pos = outfile->Tell(); - size_t pad = 16 - (pos % 16); - for (size_t i = 0; i < pad; ++i) { - outfile->Write("\x00", 1, 1); - } - - // not sure what this is, but it seems to always be 0 in modern files - for (size_t i = 0; i < 4; ++i) { - outfile->Write("\x00", 1, 1); - } - - // now the file version again - { - StreamWriterLE outstream(outfile); - outstream.PutU4(EXPORT_VERSION_INT); - } // StreamWriter destructor writes the data to the file - - // and finally some binary footer added to all files - for (size_t i = 0; i < 120; ++i) { - outfile->Write("\x00", 1, 1); - } - outfile->Write(FOOT_MAGIC.c_str(), FOOT_MAGIC.size(), 1); -} - -void FBXExporter::WriteAllNodes () -{ - // header - // (and fileid, creation time, creator, if binary) - WriteHeaderExtension(); - - // global settings - WriteGlobalSettings(); - - // documents - WriteDocuments(); - - // references - WriteReferences(); - - // definitions - WriteDefinitions(); - - // objects - WriteObjects(); - - // connections - WriteConnections(); - - // WriteTakes? (deprecated since at least 2015 (fbx 7.4)) -} - -//FBXHeaderExtension top-level node -void FBXExporter::WriteHeaderExtension () -{ - if (!binary) { - // no title, follows directly from the top comment - } - FBX::Node n("FBXHeaderExtension"); - StreamWriterLE outstream(outfile); - int indent = 0; - - // begin node - n.Begin(outstream, binary, indent); - - // write properties - // (none) - - // finish properties - n.EndProperties(outstream, binary, indent, 0); - - // begin children - n.BeginChildren(outstream, binary, indent); - - indent = 1; - - // write child nodes - FBX::Node::WritePropertyNode( - "FBXHeaderVersion", int32_t(1003), outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "FBXVersion", int32_t(EXPORT_VERSION_INT), outstream, binary, indent - ); - if (binary) { - FBX::Node::WritePropertyNode( - "EncryptionType", int32_t(0), outstream, binary, indent - ); - } - - FBX::Node CreationTimeStamp("CreationTimeStamp"); - time_t rawtime; - time(&rawtime); - struct tm * now = localtime(&rawtime); - CreationTimeStamp.AddChild("Version", int32_t(1000)); - CreationTimeStamp.AddChild("Year", int32_t(now->tm_year + 1900)); - CreationTimeStamp.AddChild("Month", int32_t(now->tm_mon + 1)); - CreationTimeStamp.AddChild("Day", int32_t(now->tm_mday)); - CreationTimeStamp.AddChild("Hour", int32_t(now->tm_hour)); - CreationTimeStamp.AddChild("Minute", int32_t(now->tm_min)); - CreationTimeStamp.AddChild("Second", int32_t(now->tm_sec)); - CreationTimeStamp.AddChild("Millisecond", int32_t(0)); - CreationTimeStamp.Dump(outstream, binary, indent); - - std::stringstream creator; - creator << "Open Asset Import Library (Assimp) " << aiGetVersionMajor() - << "." << aiGetVersionMinor() << "." << aiGetVersionRevision(); - FBX::Node::WritePropertyNode( - "Creator", creator.str(), outstream, binary, indent - ); - - //FBX::Node sceneinfo("SceneInfo"); - //sceneinfo.AddProperty("GlobalInfo" + FBX::SEPARATOR + "SceneInfo"); - // not sure if any of this is actually needed, - // so just write an empty node for now. - //sceneinfo.Dump(outstream, binary, indent); - - indent = 0; - - // finish node - n.End(outstream, binary, indent, true); - - // that's it for FBXHeaderExtension... - if (!binary) { return; } - - // but binary files also need top-level FileID, CreationTime, Creator: - std::vector<uint8_t> raw(GENERIC_FILEID.size()); - for (size_t i = 0; i < GENERIC_FILEID.size(); ++i) { - raw[i] = uint8_t(GENERIC_FILEID[i]); - } - FBX::Node::WritePropertyNode( - "FileId", raw, outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "CreationTime", GENERIC_CTIME, outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "Creator", creator.str(), outstream, binary, indent - ); -} - -void FBXExporter::WriteGlobalSettings () -{ - if (!binary) { - // no title, follows directly from the header extension - } - FBX::Node gs("GlobalSettings"); - gs.AddChild("Version", int32_t(1000)); - - FBX::Node p("Properties70"); - p.AddP70int("UpAxis", 1); - p.AddP70int("UpAxisSign", 1); - p.AddP70int("FrontAxis", 2); - p.AddP70int("FrontAxisSign", 1); - p.AddP70int("CoordAxis", 0); - p.AddP70int("CoordAxisSign", 1); - p.AddP70int("OriginalUpAxis", 1); - p.AddP70int("OriginalUpAxisSign", 1); - p.AddP70double("UnitScaleFactor", 1.0); - p.AddP70double("OriginalUnitScaleFactor", 1.0); - p.AddP70color("AmbientColor", 0.0, 0.0, 0.0); - p.AddP70string("DefaultCamera", "Producer Perspective"); - p.AddP70enum("TimeMode", 11); - p.AddP70enum("TimeProtocol", 2); - p.AddP70enum("SnapOnFrameMode", 0); - p.AddP70time("TimeSpanStart", 0); // TODO: animation support - p.AddP70time("TimeSpanStop", FBX::SECOND); // TODO: animation support - p.AddP70double("CustomFrameRate", -1.0); - p.AddP70("TimeMarker", "Compound", "", ""); // not sure what this is - p.AddP70int("CurrentTimeMarker", -1); - gs.AddChild(p); - - gs.Dump(outfile, binary, 0); -} - -void FBXExporter::WriteDocuments () -{ - if (!binary) { - WriteAsciiSectionHeader("Documents Description"); - } - - // not sure what the use of multiple documents would be, - // or whether any end-application supports it - FBX::Node docs("Documents"); - docs.AddChild("Count", int32_t(1)); - FBX::Node doc("Document"); - - // generate uid - int64_t uid = generate_uid(); - doc.AddProperties(uid, "", "Scene"); - FBX::Node p("Properties70"); - p.AddP70("SourceObject", "object", "", ""); // what is this even for? - p.AddP70string("ActiveAnimStackName", ""); // should do this properly? - doc.AddChild(p); - - // UID for root node in scene hierarchy. - // always set to 0 in the case of a single document. - // not sure what happens if more than one document exists, - // but that won't matter to us as we're exporting a single scene. - doc.AddChild("RootNode", int64_t(0)); - - docs.AddChild(doc); - docs.Dump(outfile, binary, 0); -} - -void FBXExporter::WriteReferences () -{ - if (!binary) { - WriteAsciiSectionHeader("Document References"); - } - // always empty for now. - // not really sure what this is for. - FBX::Node n("References"); - n.force_has_children = true; - n.Dump(outfile, binary, 0); -} - - -// --------------------------------------------------------------- -// some internal helper functions used for writing the definitions -// (before any actual data is written) -// --------------------------------------------------------------- - -size_t count_nodes(const aiNode* n) { - size_t count = 1; - for (size_t i = 0; i < n->mNumChildren; ++i) { - count += count_nodes(n->mChildren[i]); - } - return count; -} - -bool has_phong_mat(const aiScene* scene) -{ - // just search for any material with a shininess exponent - for (size_t i = 0; i < scene->mNumMaterials; ++i) { - aiMaterial* mat = scene->mMaterials[i]; - float shininess = 0; - mat->Get(AI_MATKEY_SHININESS, shininess); - if (shininess > 0) { - return true; - } - } - return false; -} - -size_t count_images(const aiScene* scene) { - std::unordered_set<std::string> images; - aiString texpath; - for (size_t i = 0; i < scene->mNumMaterials; ++i) { - aiMaterial* mat = scene->mMaterials[i]; - for ( - size_t tt = aiTextureType_DIFFUSE; - tt < aiTextureType_UNKNOWN; - ++tt - ){ - const aiTextureType textype = static_cast<aiTextureType>(tt); - const size_t texcount = mat->GetTextureCount(textype); - for (unsigned int j = 0; j < texcount; ++j) { - mat->GetTexture(textype, j, &texpath); - images.insert(std::string(texpath.C_Str())); - } - } - } - return images.size(); -} - -size_t count_textures(const aiScene* scene) { - size_t count = 0; - for (size_t i = 0; i < scene->mNumMaterials; ++i) { - aiMaterial* mat = scene->mMaterials[i]; - for ( - size_t tt = aiTextureType_DIFFUSE; - tt < aiTextureType_UNKNOWN; - ++tt - ){ - // TODO: handle layered textures - if (mat->GetTextureCount(static_cast<aiTextureType>(tt)) > 0) { - count += 1; - } - } - } - return count; -} - -size_t count_deformers(const aiScene* scene) { - size_t count = 0; - for (size_t i = 0; i < scene->mNumMeshes; ++i) { - const size_t n = scene->mMeshes[i]->mNumBones; - if (n) { - // 1 main deformer, 1 subdeformer per bone - count += n + 1; - } - } - return count; -} - -void FBXExporter::WriteDefinitions () -{ - // basically this is just bookkeeping: - // determining how many of each type of object there are - // and specifying the base properties to use when otherwise unspecified. - - // ascii section header - if (!binary) { - WriteAsciiSectionHeader("Object definitions"); - } - - // we need to count the objects - int32_t count; - int32_t total_count = 0; - - // and store them - std::vector<FBX::Node> object_nodes; - FBX::Node n, pt, p; - - // GlobalSettings - // this seems to always be here in Maya exports - n = FBX::Node("ObjectType", "GlobalSettings"); - count = 1; - n.AddChild("Count", count); - object_nodes.push_back(n); - total_count += count; - - // AnimationStack / FbxAnimStack - // this seems to always be here in Maya exports, - // but no harm seems to come of leaving it out. - count = mScene->mNumAnimations; - if (count) { - n = FBX::Node("ObjectType", "AnimationStack"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxAnimStack"); - p = FBX::Node("Properties70"); - p.AddP70string("Description", ""); - p.AddP70time("LocalStart", 0); - p.AddP70time("LocalStop", 0); - p.AddP70time("ReferenceStart", 0); - p.AddP70time("ReferenceStop", 0); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // AnimationLayer / FbxAnimLayer - // this seems to always be here in Maya exports, - // but no harm seems to come of leaving it out. - // Assimp doesn't support animation layers, - // so there will be one per aiAnimation - count = mScene->mNumAnimations; - if (count) { - n = FBX::Node("ObjectType", "AnimationLayer"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FBXAnimLayer"); - p = FBX::Node("Properties70"); - p.AddP70("Weight", "Number", "", "A", double(100)); - p.AddP70bool("Mute", 0); - p.AddP70bool("Solo", 0); - p.AddP70bool("Lock", 0); - p.AddP70color("Color", 0.8, 0.8, 0.8); - p.AddP70("BlendMode", "enum", "", "", int32_t(0)); - p.AddP70("RotationAccumulationMode", "enum", "", "", int32_t(0)); - p.AddP70("ScaleAccumulationMode", "enum", "", "", int32_t(0)); - p.AddP70("BlendModeBypass", "ULongLong", "", "", int64_t(0)); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // NodeAttribute - // this is completely absurd. - // there can only be one "NodeAttribute" template, - // but FbxSkeleton, FbxCamera, FbxLight all are "NodeAttributes". - // so if only one exists we should set the template for that, - // otherwise... we just pick one :/. - // the others have to set all their properties every instance, - // because there's no template. - count = 1; // TODO: select properly - if (count) { - // FbxSkeleton - n = FBX::Node("ObjectType", "NodeAttribute"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxSkeleton"); - p = FBX::Node("Properties70"); - p.AddP70color("Color", 0.8, 0.8, 0.8); - p.AddP70double("Size", 33.333333333333); - p.AddP70("LimbLength", "double", "Number", "H", double(1)); - // note: not sure what the "H" flag is for - hidden? - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // Model / FbxNode - // <~~ node hierarchy - count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node) - if (count) { - n = FBX::Node("ObjectType", "Model"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxNode"); - p = FBX::Node("Properties70"); - p.AddP70enum("QuaternionInterpolate", 0); - p.AddP70vector("RotationOffset", 0.0, 0.0, 0.0); - p.AddP70vector("RotationPivot", 0.0, 0.0, 0.0); - p.AddP70vector("ScalingOffset", 0.0, 0.0, 0.0); - p.AddP70vector("ScalingPivot", 0.0, 0.0, 0.0); - p.AddP70bool("TranslationActive", 0); - p.AddP70vector("TranslationMin", 0.0, 0.0, 0.0); - p.AddP70vector("TranslationMax", 0.0, 0.0, 0.0); - p.AddP70bool("TranslationMinX", 0); - p.AddP70bool("TranslationMinY", 0); - p.AddP70bool("TranslationMinZ", 0); - p.AddP70bool("TranslationMaxX", 0); - p.AddP70bool("TranslationMaxY", 0); - p.AddP70bool("TranslationMaxZ", 0); - p.AddP70enum("RotationOrder", 0); - p.AddP70bool("RotationSpaceForLimitOnly", 0); - p.AddP70double("RotationStiffnessX", 0.0); - p.AddP70double("RotationStiffnessY", 0.0); - p.AddP70double("RotationStiffnessZ", 0.0); - p.AddP70double("AxisLen", 10.0); - p.AddP70vector("PreRotation", 0.0, 0.0, 0.0); - p.AddP70vector("PostRotation", 0.0, 0.0, 0.0); - p.AddP70bool("RotationActive", 0); - p.AddP70vector("RotationMin", 0.0, 0.0, 0.0); - p.AddP70vector("RotationMax", 0.0, 0.0, 0.0); - p.AddP70bool("RotationMinX", 0); - p.AddP70bool("RotationMinY", 0); - p.AddP70bool("RotationMinZ", 0); - p.AddP70bool("RotationMaxX", 0); - p.AddP70bool("RotationMaxY", 0); - p.AddP70bool("RotationMaxZ", 0); - p.AddP70enum("InheritType", 0); - p.AddP70bool("ScalingActive", 0); - p.AddP70vector("ScalingMin", 0.0, 0.0, 0.0); - p.AddP70vector("ScalingMax", 1.0, 1.0, 1.0); - p.AddP70bool("ScalingMinX", 0); - p.AddP70bool("ScalingMinY", 0); - p.AddP70bool("ScalingMinZ", 0); - p.AddP70bool("ScalingMaxX", 0); - p.AddP70bool("ScalingMaxY", 0); - p.AddP70bool("ScalingMaxZ", 0); - p.AddP70vector("GeometricTranslation", 0.0, 0.0, 0.0); - p.AddP70vector("GeometricRotation", 0.0, 0.0, 0.0); - p.AddP70vector("GeometricScaling", 1.0, 1.0, 1.0); - p.AddP70double("MinDampRangeX", 0.0); - p.AddP70double("MinDampRangeY", 0.0); - p.AddP70double("MinDampRangeZ", 0.0); - p.AddP70double("MaxDampRangeX", 0.0); - p.AddP70double("MaxDampRangeY", 0.0); - p.AddP70double("MaxDampRangeZ", 0.0); - p.AddP70double("MinDampStrengthX", 0.0); - p.AddP70double("MinDampStrengthY", 0.0); - p.AddP70double("MinDampStrengthZ", 0.0); - p.AddP70double("MaxDampStrengthX", 0.0); - p.AddP70double("MaxDampStrengthY", 0.0); - p.AddP70double("MaxDampStrengthZ", 0.0); - p.AddP70double("PreferedAngleX", 0.0); - p.AddP70double("PreferedAngleY", 0.0); - p.AddP70double("PreferedAngleZ", 0.0); - p.AddP70("LookAtProperty", "object", "", ""); - p.AddP70("UpVectorProperty", "object", "", ""); - p.AddP70bool("Show", 1); - p.AddP70bool("NegativePercentShapeSupport", 1); - p.AddP70int("DefaultAttributeIndex", -1); - p.AddP70bool("Freeze", 0); - p.AddP70bool("LODBox", 0); - p.AddP70( - "Lcl Translation", "Lcl Translation", "", "A", - double(0), double(0), double(0) - ); - p.AddP70( - "Lcl Rotation", "Lcl Rotation", "", "A", - double(0), double(0), double(0) - ); - p.AddP70( - "Lcl Scaling", "Lcl Scaling", "", "A", - double(1), double(1), double(1) - ); - p.AddP70("Visibility", "Visibility", "", "A", double(1)); - p.AddP70( - "Visibility Inheritance", "Visibility Inheritance", "", "", - int32_t(1) - ); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // Geometry / FbxMesh - // <~~ aiMesh - count = mScene->mNumMeshes; - if (count) { - n = FBX::Node("ObjectType", "Geometry"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxMesh"); - p = FBX::Node("Properties70"); - p.AddP70color("Color", 0, 0, 0); - p.AddP70vector("BBoxMin", 0, 0, 0); - p.AddP70vector("BBoxMax", 0, 0, 0); - p.AddP70bool("Primary Visibility", 1); - p.AddP70bool("Casts Shadows", 1); - p.AddP70bool("Receive Shadows", 1); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // Material / FbxSurfacePhong, FbxSurfaceLambert, FbxSurfaceMaterial - // <~~ aiMaterial - // basically if there's any phong material this is defined as phong, - // and otherwise lambert. - // More complex materials cause a bare-bones FbxSurfaceMaterial definition - // and are treated specially, as they're not really supported by FBX. - // TODO: support Maya's Stingray PBS material - count = mScene->mNumMaterials; - if (count) { - bool has_phong = has_phong_mat(mScene); - n = FBX::Node("ObjectType", "Material"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate"); - if (has_phong) { - pt.AddProperty("FbxSurfacePhong"); - } else { - pt.AddProperty("FbxSurfaceLambert"); - } - p = FBX::Node("Properties70"); - if (has_phong) { - p.AddP70string("ShadingModel", "Phong"); - } else { - p.AddP70string("ShadingModel", "Lambert"); - } - p.AddP70bool("MultiLayer", 0); - p.AddP70colorA("EmissiveColor", 0.0, 0.0, 0.0); - p.AddP70numberA("EmissiveFactor", 1.0); - p.AddP70colorA("AmbientColor", 0.2, 0.2, 0.2); - p.AddP70numberA("AmbientFactor", 1.0); - p.AddP70colorA("DiffuseColor", 0.8, 0.8, 0.8); - p.AddP70numberA("DiffuseFactor", 1.0); - p.AddP70vector("Bump", 0.0, 0.0, 0.0); - p.AddP70vector("NormalMap", 0.0, 0.0, 0.0); - p.AddP70double("BumpFactor", 1.0); - p.AddP70colorA("TransparentColor", 0.0, 0.0, 0.0); - p.AddP70numberA("TransparencyFactor", 0.0); - p.AddP70color("DisplacementColor", 0.0, 0.0, 0.0); - p.AddP70double("DisplacementFactor", 1.0); - p.AddP70color("VectorDisplacementColor", 0.0, 0.0, 0.0); - p.AddP70double("VectorDisplacementFactor", 1.0); - if (has_phong) { - p.AddP70colorA("SpecularColor", 0.2, 0.2, 0.2); - p.AddP70numberA("SpecularFactor", 1.0); - p.AddP70numberA("ShininessExponent", 20.0); - p.AddP70colorA("ReflectionColor", 0.0, 0.0, 0.0); - p.AddP70numberA("ReflectionFactor", 1.0); - } - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // Video / FbxVideo - // one for each image file. - count = int32_t(count_images(mScene)); - if (count) { - n = FBX::Node("ObjectType", "Video"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxVideo"); - p = FBX::Node("Properties70"); - p.AddP70bool("ImageSequence", 0); - p.AddP70int("ImageSequenceOffset", 0); - p.AddP70double("FrameRate", 0.0); - p.AddP70int("LastFrame", 0); - p.AddP70int("Width", 0); - p.AddP70int("Height", 0); - p.AddP70("Path", "KString", "XRefUrl", "", ""); - p.AddP70int("StartFrame", 0); - p.AddP70int("StopFrame", 0); - p.AddP70double("PlaySpeed", 0.0); - p.AddP70time("Offset", 0); - p.AddP70enum("InterlaceMode", 0); - p.AddP70bool("FreeRunning", 0); - p.AddP70bool("Loop", 0); - p.AddP70enum("AccessMode", 0); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // Texture / FbxFileTexture - // <~~ aiTexture - count = int32_t(count_textures(mScene)); - if (count) { - n = FBX::Node("ObjectType", "Texture"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxFileTexture"); - p = FBX::Node("Properties70"); - p.AddP70enum("TextureTypeUse", 0); - p.AddP70numberA("Texture alpha", 1.0); - p.AddP70enum("CurrentMappingType", 0); - p.AddP70enum("WrapModeU", 0); - p.AddP70enum("WrapModeV", 0); - p.AddP70bool("UVSwap", 0); - p.AddP70bool("PremultiplyAlpha", 1); - p.AddP70vectorA("Translation", 0.0, 0.0, 0.0); - p.AddP70vectorA("Rotation", 0.0, 0.0, 0.0); - p.AddP70vectorA("Scaling", 1.0, 1.0, 1.0); - p.AddP70vector("TextureRotationPivot", 0.0, 0.0, 0.0); - p.AddP70vector("TextureScalingPivot", 0.0, 0.0, 0.0); - p.AddP70enum("CurrentTextureBlendMode", 1); - p.AddP70string("UVSet", "default"); - p.AddP70bool("UseMaterial", 0); - p.AddP70bool("UseMipMap", 0); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // AnimationCurveNode / FbxAnimCurveNode - count = mScene->mNumAnimations * 3; - if (count) { - n = FBX::Node("ObjectType", "AnimationCurveNode"); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", "FbxAnimCurveNode"); - p = FBX::Node("Properties70"); - p.AddP70("d", "Compound", "", ""); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // AnimationCurve / FbxAnimCurve - count = mScene->mNumAnimations * 9; - if (count) { - n = FBX::Node("ObjectType", "AnimationCurve"); - n.AddChild("Count", count); - object_nodes.push_back(n); - total_count += count; - } - - // Pose - count = 0; - for (size_t i = 0; i < mScene->mNumMeshes; ++i) { - aiMesh* mesh = mScene->mMeshes[i]; - if (mesh->HasBones()) { ++count; } - } - if (count) { - n = FBX::Node("ObjectType", "Pose"); - n.AddChild("Count", count); - object_nodes.push_back(n); - total_count += count; - } - - // Deformer - count = int32_t(count_deformers(mScene)); - if (count) { - n = FBX::Node("ObjectType", "Deformer"); - n.AddChild("Count", count); - object_nodes.push_back(n); - total_count += count; - } - - // (template) - count = 0; - if (count) { - n = FBX::Node("ObjectType", ""); - n.AddChild("Count", count); - pt = FBX::Node("PropertyTemplate", ""); - p = FBX::Node("Properties70"); - pt.AddChild(p); - n.AddChild(pt); - object_nodes.push_back(n); - total_count += count; - } - - // now write it all - FBX::Node defs("Definitions"); - defs.AddChild("Version", int32_t(100)); - defs.AddChild("Count", int32_t(total_count)); - for (auto &n : object_nodes) { defs.AddChild(n); } - defs.Dump(outfile, binary, 0); -} - - -// ------------------------------------------------------------------- -// some internal helper functions used for writing the objects section -// (which holds the actual data) -// ------------------------------------------------------------------- - -aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node) -{ - for (size_t i = 0; i < node->mNumMeshes; ++i) { - if (node->mMeshes[i] == meshIndex) { - return node; - } - } - for (size_t i = 0; i < node->mNumChildren; ++i) { - aiNode* ret = get_node_for_mesh(meshIndex, node->mChildren[i]); - if (ret) { return ret; } - } - return nullptr; -} - -aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) -{ - std::vector<const aiNode*> node_chain; - while (node != scene->mRootNode) { - node_chain.push_back(node); - node = node->mParent; - } - aiMatrix4x4 transform; - for (auto n = node_chain.rbegin(); n != node_chain.rend(); ++n) { - transform *= (*n)->mTransformation; - } - return transform; -} - -int64_t to_ktime(double ticks, const aiAnimation* anim) { - if (anim->mTicksPerSecond <= 0) { - return static_cast<int64_t>(ticks) * FBX::SECOND; - } - return (static_cast<int64_t>(ticks) / static_cast<int64_t>(anim->mTicksPerSecond)) * FBX::SECOND; -} - -int64_t to_ktime(double time) { - return (static_cast<int64_t>(time * FBX::SECOND)); -} - -void FBXExporter::WriteObjects () -{ - if (!binary) { - WriteAsciiSectionHeader("Object properties"); - } - // numbers should match those given in definitions! make sure to check - StreamWriterLE outstream(outfile); - FBX::Node object_node("Objects"); - int indent = 0; - object_node.Begin(outstream, binary, indent); - object_node.EndProperties(outstream, binary, indent); - object_node.BeginChildren(outstream, binary, indent); - - bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true); - std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later - - // geometry (aiMesh) - mesh_uids.clear(); - indent = 1; - for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) { - // it's all about this mesh - aiMesh* m = mScene->mMeshes[mi]; - - // start the node record - FBX::Node n("Geometry"); - int64_t uid = generate_uid(); - mesh_uids.push_back(uid); - n.AddProperty(uid); - n.AddProperty(FBX::SEPARATOR + "Geometry"); - n.AddProperty("Mesh"); - n.Begin(outstream, binary, indent); - n.DumpProperties(outstream, binary, indent); - n.EndProperties(outstream, binary, indent); - n.BeginChildren(outstream, binary, indent); - indent = 2; - - // output vertex data - each vertex should be unique (probably) - std::vector<double> flattened_vertices; - // index of original vertex in vertex data vector - std::vector<int32_t> vertex_indices; - // map of vertex value to its index in the data vector - std::map<aiVector3D,size_t> index_by_vertex_value; - if(bJoinIdenticalVertices){ - int32_t index = 0; - for (size_t vi = 0; vi < m->mNumVertices; ++vi) { - aiVector3D vtx = m->mVertices[vi]; - auto elem = index_by_vertex_value.find(vtx); - if (elem == index_by_vertex_value.end()) { - vertex_indices.push_back(index); - index_by_vertex_value[vtx] = index; - flattened_vertices.push_back(vtx[0]); - flattened_vertices.push_back(vtx[1]); - flattened_vertices.push_back(vtx[2]); - ++index; - } else { - vertex_indices.push_back(int32_t(elem->second)); - } - } - } - else { // do not join vertex, respect the export flag - vertex_indices.resize(m->mNumVertices); - std::iota(vertex_indices.begin(), vertex_indices.end(), 0); - for(unsigned int v = 0; v < m->mNumVertices; ++ v) { - aiVector3D vtx = m->mVertices[v]; - flattened_vertices.push_back(vtx.x); - flattened_vertices.push_back(vtx.y); - flattened_vertices.push_back(vtx.z); - } - } - vVertexIndice.push_back(vertex_indices); - - FBX::Node::WritePropertyNode( - "Vertices", flattened_vertices, outstream, binary, indent - ); - - // output polygon data as a flattened array of vertex indices. - // the last vertex index of each polygon is negated and - 1 - std::vector<int32_t> polygon_data; - for (size_t fi = 0; fi < m->mNumFaces; ++fi) { - const aiFace &f = m->mFaces[fi]; - for (size_t pvi = 0; pvi < f.mNumIndices - 1; ++pvi) { - polygon_data.push_back(vertex_indices[f.mIndices[pvi]]); - } - polygon_data.push_back( - -1 - vertex_indices[f.mIndices[f.mNumIndices-1]] - ); - } - FBX::Node::WritePropertyNode( - "PolygonVertexIndex", polygon_data, outstream, binary, indent - ); - - // here could be edges but they're insane. - // it's optional anyway, so let's ignore it. - - FBX::Node::WritePropertyNode( - "GeometryVersion", int32_t(124), outstream, binary, indent - ); - - // normals, if any - if (m->HasNormals()) { - FBX::Node normals("LayerElementNormal", int32_t(0)); - normals.Begin(outstream, binary, indent); - normals.DumpProperties(outstream, binary, indent); - normals.EndProperties(outstream, binary, indent); - normals.BeginChildren(outstream, binary, indent); - indent = 3; - FBX::Node::WritePropertyNode( - "Version", int32_t(101), outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "Name", "", outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "MappingInformationType", "ByPolygonVertex", - outstream, binary, indent - ); - // TODO: vertex-normals or indexed normals when appropriate - FBX::Node::WritePropertyNode( - "ReferenceInformationType", "Direct", - outstream, binary, indent - ); - std::vector<double> normal_data; - normal_data.reserve(3 * polygon_data.size()); - for (size_t fi = 0; fi < m->mNumFaces; ++fi) { - const aiFace &f = m->mFaces[fi]; - for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { - const aiVector3D &n = m->mNormals[f.mIndices[pvi]]; - normal_data.push_back(n.x); - normal_data.push_back(n.y); - normal_data.push_back(n.z); - } - } - FBX::Node::WritePropertyNode( - "Normals", normal_data, outstream, binary, indent - ); - // note: version 102 has a NormalsW also... not sure what it is, - // so we can stick with version 101 for now. - indent = 2; - normals.End(outstream, binary, indent, true); - } - - // colors, if any - // TODO only one color channel currently - const int32_t colorChannelIndex = 0; - if (m->HasVertexColors(colorChannelIndex)) { - FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex)); - vertexcolors.Begin(outstream, binary, indent); - vertexcolors.DumpProperties(outstream, binary, indent); - vertexcolors.EndProperties(outstream, binary, indent); - vertexcolors.BeginChildren(outstream, binary, indent); - indent = 3; - FBX::Node::WritePropertyNode( - "Version", int32_t(101), outstream, binary, indent - ); - char layerName[8]; - sprintf(layerName, "COLOR_%d", colorChannelIndex); - FBX::Node::WritePropertyNode( - "Name", (const char*)layerName, outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "MappingInformationType", "ByPolygonVertex", - outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "ReferenceInformationType", "Direct", - outstream, binary, indent - ); - std::vector<double> color_data; - color_data.reserve(4 * polygon_data.size()); - for (size_t fi = 0; fi < m->mNumFaces; ++fi) { - const aiFace &f = m->mFaces[fi]; - for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { - const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]]; - color_data.push_back(c.r); - color_data.push_back(c.g); - color_data.push_back(c.b); - color_data.push_back(c.a); - } - } - FBX::Node::WritePropertyNode( - "Colors", color_data, outstream, binary, indent - ); - indent = 2; - vertexcolors.End(outstream, binary, indent, true); - } - - // uvs, if any - for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) { - if (m->mNumUVComponents[uvi] > 2) { - // FBX only supports 2-channel UV maps... - // or at least i'm not sure how to indicate a different number - std::stringstream err; - err << "Only 2-channel UV maps supported by FBX,"; - err << " but mesh " << mi; - if (m->mName.length) { - err << " (" << m->mName.C_Str() << ")"; - } - err << " UV map " << uvi; - err << " has " << m->mNumUVComponents[uvi]; - err << " components! Data will be preserved,"; - err << " but may be incorrectly interpreted on load."; - ASSIMP_LOG_WARN(err.str()); - } - FBX::Node uv("LayerElementUV", int32_t(uvi)); - uv.Begin(outstream, binary, indent); - uv.DumpProperties(outstream, binary, indent); - uv.EndProperties(outstream, binary, indent); - uv.BeginChildren(outstream, binary, indent); - indent = 3; - FBX::Node::WritePropertyNode( - "Version", int32_t(101), outstream, binary, indent - ); - // it doesn't seem like assimp keeps the uv map name, - // so just leave it blank. - FBX::Node::WritePropertyNode( - "Name", "", outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "MappingInformationType", "ByPolygonVertex", - outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "ReferenceInformationType", "IndexToDirect", - outstream, binary, indent - ); - - std::vector<double> uv_data; - std::vector<int32_t> uv_indices; - std::map<aiVector3D,int32_t> index_by_uv; - int32_t index = 0; - for (size_t fi = 0; fi < m->mNumFaces; ++fi) { - const aiFace &f = m->mFaces[fi]; - for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { - const aiVector3D &uv = - m->mTextureCoords[uvi][f.mIndices[pvi]]; - auto elem = index_by_uv.find(uv); - if (elem == index_by_uv.end()) { - index_by_uv[uv] = index; - uv_indices.push_back(index); - for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) { - uv_data.push_back(uv[x]); - } - ++index; - } else { - uv_indices.push_back(elem->second); - } - } - } - FBX::Node::WritePropertyNode( - "UV", uv_data, outstream, binary, indent - ); - FBX::Node::WritePropertyNode( - "UVIndex", uv_indices, outstream, binary, indent - ); - indent = 2; - uv.End(outstream, binary, indent, true); - } - - // i'm not really sure why this material section exists, - // as the material is linked via "Connections". - // it seems to always have the same "0" value. - FBX::Node mat("LayerElementMaterial", int32_t(0)); - mat.AddChild("Version", int32_t(101)); - mat.AddChild("Name", ""); - mat.AddChild("MappingInformationType", "AllSame"); - mat.AddChild("ReferenceInformationType", "IndexToDirect"); - std::vector<int32_t> mat_indices = {0}; - mat.AddChild("Materials", mat_indices); - mat.Dump(outstream, binary, indent); - - // finally we have the layer specifications, - // which select the normals / UV set / etc to use. - // TODO: handle multiple uv sets correctly? - FBX::Node layer("Layer", int32_t(0)); - layer.AddChild("Version", int32_t(100)); - FBX::Node le("LayerElement"); - le.AddChild("Type", "LayerElementNormal"); - le.AddChild("TypedIndex", int32_t(0)); - layer.AddChild(le); - // TODO only 1 color channel currently - le = FBX::Node("LayerElement"); - le.AddChild("Type", "LayerElementColor"); - le.AddChild("TypedIndex", int32_t(0)); - layer.AddChild(le); - le = FBX::Node("LayerElement"); - le.AddChild("Type", "LayerElementMaterial"); - le.AddChild("TypedIndex", int32_t(0)); - layer.AddChild(le); - le = FBX::Node("LayerElement"); - le.AddChild("Type", "LayerElementUV"); - le.AddChild("TypedIndex", int32_t(0)); - layer.AddChild(le); - layer.Dump(outstream, binary, indent); - - for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr) - { - FBX::Node layerExtra("Layer", int32_t(lr)); - layerExtra.AddChild("Version", int32_t(100)); - FBX::Node leExtra("LayerElement"); - leExtra.AddChild("Type", "LayerElementUV"); - leExtra.AddChild("TypedIndex", int32_t(lr)); - layerExtra.AddChild(leExtra); - layerExtra.Dump(outstream, binary, indent); - } - // finish the node record - indent = 1; - n.End(outstream, binary, indent, true); - } - - // aiMaterial - material_uids.clear(); - for (size_t i = 0; i < mScene->mNumMaterials; ++i) { - // it's all about this material - aiMaterial* m = mScene->mMaterials[i]; - - // these are used to receive material data - float f; aiColor3D c; - - // start the node record - FBX::Node n("Material"); - - int64_t uid = generate_uid(); - material_uids.push_back(uid); - n.AddProperty(uid); - - aiString name; - m->Get(AI_MATKEY_NAME, name); - n.AddProperty(name.C_Str() + FBX::SEPARATOR + "Material"); - - n.AddProperty(""); - - n.AddChild("Version", int32_t(102)); - f = 0; - m->Get(AI_MATKEY_SHININESS, f); - bool phong = (f > 0); - if (phong) { - n.AddChild("ShadingModel", "phong"); - } else { - n.AddChild("ShadingModel", "lambert"); - } - n.AddChild("MultiLayer", int32_t(0)); - - FBX::Node p("Properties70"); - - // materials exported using the FBX SDK have two sets of fields. - // there are the properties specified in the PropertyTemplate, - // which are those supported by the modernFBX SDK, - // and an extra set of properties with simpler names. - // The extra properties are a legacy material system from pre-2009. - // - // In the modern system, each property has "color" and "factor". - // Generally the interpretation of these seems to be - // that the colour is multiplied by the factor before use, - // but this is not always clear-cut. - // - // Usually assimp only stores the colour, - // so we can just leave the factors at the default "1.0". - - // first we can export the "standard" properties - if (m->Get(AI_MATKEY_COLOR_AMBIENT, c) == aiReturn_SUCCESS) { - p.AddP70colorA("AmbientColor", c.r, c.g, c.b); - //p.AddP70numberA("AmbientFactor", 1.0); - } - if (m->Get(AI_MATKEY_COLOR_DIFFUSE, c) == aiReturn_SUCCESS) { - p.AddP70colorA("DiffuseColor", c.r, c.g, c.b); - //p.AddP70numberA("DiffuseFactor", 1.0); - } - if (m->Get(AI_MATKEY_COLOR_TRANSPARENT, c) == aiReturn_SUCCESS) { - // "TransparentColor" / "TransparencyFactor"... - // thanks FBX, for your insightful interpretation of consistency - p.AddP70colorA("TransparentColor", c.r, c.g, c.b); - // TransparencyFactor defaults to 0.0, so set it to 1.0. - // note: Maya always sets this to 1.0, - // so we can't use it sensibly as "Opacity". - // In stead we rely on the legacy "Opacity" value, below. - // Blender also relies on "Opacity" not "TransparencyFactor", - // probably for a similar reason. - p.AddP70numberA("TransparencyFactor", 1.0); - } - if (m->Get(AI_MATKEY_COLOR_REFLECTIVE, c) == aiReturn_SUCCESS) { - p.AddP70colorA("ReflectionColor", c.r, c.g, c.b); - } - if (m->Get(AI_MATKEY_REFLECTIVITY, f) == aiReturn_SUCCESS) { - p.AddP70numberA("ReflectionFactor", f); - } - if (phong) { - if (m->Get(AI_MATKEY_COLOR_SPECULAR, c) == aiReturn_SUCCESS) { - p.AddP70colorA("SpecularColor", c.r, c.g, c.b); - } - if (m->Get(AI_MATKEY_SHININESS_STRENGTH, f) == aiReturn_SUCCESS) { - p.AddP70numberA("ShininessFactor", f); - } - if (m->Get(AI_MATKEY_SHININESS, f) == aiReturn_SUCCESS) { - p.AddP70numberA("ShininessExponent", f); - } - if (m->Get(AI_MATKEY_REFLECTIVITY, f) == aiReturn_SUCCESS) { - p.AddP70numberA("ReflectionFactor", f); - } - } - - // Now the legacy system. - // For safety let's include it. - // thrse values don't exist in the property template, - // and usually are completely ignored when loading. - // One notable exception is the "Opacity" property, - // which Blender uses as (1.0 - alpha). - c.r = 0.0f; c.g = 0.0f; c.b = 0.0f; - m->Get(AI_MATKEY_COLOR_EMISSIVE, c); - p.AddP70vector("Emissive", c.r, c.g, c.b); - c.r = 0.2f; c.g = 0.2f; c.b = 0.2f; - m->Get(AI_MATKEY_COLOR_AMBIENT, c); - p.AddP70vector("Ambient", c.r, c.g, c.b); - c.r = 0.8f; c.g = 0.8f; c.b = 0.8f; - m->Get(AI_MATKEY_COLOR_DIFFUSE, c); - p.AddP70vector("Diffuse", c.r, c.g, c.b); - // The FBX SDK determines "Opacity" from transparency colour (RGB) - // and factor (F) as: O = (1.0 - F * ((R + G + B) / 3)). - // However we actually have an opacity value, - // so we should take it from AI_MATKEY_OPACITY if possible. - // It might make more sense to use TransparencyFactor, - // but Blender actually loads "Opacity" correctly, so let's use it. - f = 1.0f; - if (m->Get(AI_MATKEY_COLOR_TRANSPARENT, c) == aiReturn_SUCCESS) { - f = 1.0f - ((c.r + c.g + c.b) / 3.0f); - } - m->Get(AI_MATKEY_OPACITY, f); - p.AddP70double("Opacity", f); - if (phong) { - // specular color is multiplied by shininess_strength - c.r = 0.2f; c.g = 0.2f; c.b = 0.2f; - m->Get(AI_MATKEY_COLOR_SPECULAR, c); - f = 1.0f; - m->Get(AI_MATKEY_SHININESS_STRENGTH, f); - p.AddP70vector("Specular", f*c.r, f*c.g, f*c.b); - f = 20.0f; - m->Get(AI_MATKEY_SHININESS, f); - p.AddP70double("Shininess", f); - // Legacy "Reflectivity" is F*F*((R+G+B)/3), - // where F is the proportion of light reflected (AKA reflectivity), - // and RGB is the reflective colour of the material. - // No idea why, but we might as well set it the same way. - f = 0.0f; - m->Get(AI_MATKEY_REFLECTIVITY, f); - c.r = 1.0f, c.g = 1.0f, c.b = 1.0f; - m->Get(AI_MATKEY_COLOR_REFLECTIVE, c); - p.AddP70double("Reflectivity", f*f*((c.r+c.g+c.b)/3.0)); - } - - n.AddChild(p); - - n.Dump(outstream, binary, indent); - } - - // we need to look up all the images we're using, - // so we can generate uids, and eliminate duplicates. - std::map<std::string, int64_t> uid_by_image; - for (size_t i = 0; i < mScene->mNumMaterials; ++i) { - aiString texpath; - aiMaterial* mat = mScene->mMaterials[i]; - for ( - size_t tt = aiTextureType_DIFFUSE; - tt < aiTextureType_UNKNOWN; - ++tt - ){ - const aiTextureType textype = static_cast<aiTextureType>(tt); - const size_t texcount = mat->GetTextureCount(textype); - for (size_t j = 0; j < texcount; ++j) { - mat->GetTexture(textype, (unsigned int)j, &texpath); - const std::string texstring = texpath.C_Str(); - auto elem = uid_by_image.find(texstring); - if (elem == uid_by_image.end()) { - uid_by_image[texstring] = generate_uid(); - } - } - } - } - - // FbxVideo - stores images used by textures. - for (const auto &it : uid_by_image) { - FBX::Node n("Video"); - const int64_t& uid = it.second; - const std::string name = ""; // TODO: ... name??? - n.AddProperties(uid, name + FBX::SEPARATOR + "Video", "Clip"); - n.AddChild("Type", "Clip"); - FBX::Node p("Properties70"); - // TODO: get full path... relative path... etc... ugh... - // for now just use the same path for everything, - // and hopefully one of them will work out. - std::string path = it.first; - // try get embedded texture - const aiTexture* embedded_texture = mScene->GetEmbeddedTexture(it.first.c_str()); - if (embedded_texture != nullptr) { - // change the path (use original filename, if available. If name is empty, concatenate texture index with file extension) - std::stringstream newPath; - if (embedded_texture->mFilename.length > 0) { - newPath << embedded_texture->mFilename.C_Str(); - } else if (embedded_texture->achFormatHint[0]) { - int texture_index = std::stoi(path.substr(1, path.size() - 1)); - newPath << texture_index << "." << embedded_texture->achFormatHint; - } - path = newPath.str(); - // embed the texture - size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u)); - if (binary) { - // embed texture as binary data - std::vector<uint8_t> tex_data; - tex_data.resize(texture_size); - memcpy(&tex_data[0], (char*)embedded_texture->pcData, texture_size); - n.AddChild("Content", tex_data); - } else { - // embed texture in base64 encoding - std::string encoded_texture = FBX::Util::EncodeBase64((char*)embedded_texture->pcData, texture_size); - n.AddChild("Content", encoded_texture); - } - } - p.AddP70("Path", "KString", "XRefUrl", "", path); - n.AddChild(p); - n.AddChild("UseMipMap", int32_t(0)); - n.AddChild("Filename", path); - n.AddChild("RelativeFilename", path); - n.Dump(outstream, binary, indent); - } - - // Textures - // referenced by material_index/texture_type pairs. - std::map<std::pair<size_t,size_t>,int64_t> texture_uids; - const std::map<aiTextureType,std::string> prop_name_by_tt = { - {aiTextureType_DIFFUSE, "DiffuseColor"}, - {aiTextureType_SPECULAR, "SpecularColor"}, - {aiTextureType_AMBIENT, "AmbientColor"}, - {aiTextureType_EMISSIVE, "EmissiveColor"}, - {aiTextureType_HEIGHT, "Bump"}, - {aiTextureType_NORMALS, "NormalMap"}, - {aiTextureType_SHININESS, "ShininessExponent"}, - {aiTextureType_OPACITY, "TransparentColor"}, - {aiTextureType_DISPLACEMENT, "DisplacementColor"}, - //{aiTextureType_LIGHTMAP, "???"}, - {aiTextureType_REFLECTION, "ReflectionColor"} - //{aiTextureType_UNKNOWN, ""} - }; - for (size_t i = 0; i < mScene->mNumMaterials; ++i) { - // textures are attached to materials - aiMaterial* mat = mScene->mMaterials[i]; - int64_t material_uid = material_uids[i]; - - for ( - size_t j = aiTextureType_DIFFUSE; - j < aiTextureType_UNKNOWN; - ++j - ) { - const aiTextureType tt = static_cast<aiTextureType>(j); - size_t n = mat->GetTextureCount(tt); - - if (n < 1) { // no texture of this type - continue; - } - - if (n > 1) { - // TODO: multilayer textures - std::stringstream err; - err << "Multilayer textures not supported (for now),"; - err << " skipping texture type " << j; - err << " of material " << i; - ASSIMP_LOG_WARN(err.str()); - } - - // get image path for this (single-image) texture - aiString tpath; - if (mat->GetTexture(tt, 0, &tpath) != aiReturn_SUCCESS) { - std::stringstream err; - err << "Failed to get texture 0 for texture of type " << tt; - err << " on material " << i; - err << ", however GetTextureCount returned 1."; - throw DeadlyExportError(err.str()); - } - const std::string texture_path(tpath.C_Str()); - - // get connected image uid - auto elem = uid_by_image.find(texture_path); - if (elem == uid_by_image.end()) { - // this should never happen - std::stringstream err; - err << "Failed to find video element for texture with path"; - err << " \"" << texture_path << "\""; - err << ", type " << j << ", material " << i; - throw DeadlyExportError(err.str()); - } - const int64_t image_uid = elem->second; - - // get the name of the material property to connect to - auto elem2 = prop_name_by_tt.find(tt); - if (elem2 == prop_name_by_tt.end()) { - // don't know how to handle this type of texture, - // so skip it. - std::stringstream err; - err << "Not sure how to handle texture of type " << j; - err << " on material " << i; - err << ", skipping..."; - ASSIMP_LOG_WARN(err.str()); - continue; - } - const std::string& prop_name = elem2->second; - - // generate a uid for this texture - const int64_t texture_uid = generate_uid(); - - // link the texture to the material - connections.emplace_back( - "C", "OP", texture_uid, material_uid, prop_name - ); - - // link the image data to the texture - connections.emplace_back("C", "OO", image_uid, texture_uid); - - // now write the actual texture node - FBX::Node tnode("Texture"); - // TODO: some way to determine texture name? - const std::string texture_name = "" + FBX::SEPARATOR + "Texture"; - tnode.AddProperties(texture_uid, texture_name, ""); - // there really doesn't seem to be a better type than this: - tnode.AddChild("Type", "TextureVideoClip"); - tnode.AddChild("Version", int32_t(202)); - tnode.AddChild("TextureName", texture_name); - FBX::Node p("Properties70"); - p.AddP70enum("CurrentTextureBlendMode", 0); // TODO: verify - //p.AddP70string("UVSet", ""); // TODO: how should this work? - p.AddP70bool("UseMaterial", 1); - tnode.AddChild(p); - // can't easily detrmine which texture path will be correct, - // so just store what we have in every field. - // these being incorrect is a common problem with FBX anyway. - tnode.AddChild("FileName", texture_path); - tnode.AddChild("RelativeFilename", texture_path); - tnode.AddChild("ModelUVTranslation", double(0.0), double(0.0)); - tnode.AddChild("ModelUVScaling", double(1.0), double(1.0)); - tnode.AddChild("Texture_Alpha_Source", "None"); - tnode.AddChild( - "Cropping", int32_t(0), int32_t(0), int32_t(0), int32_t(0) - ); - tnode.Dump(outstream, binary, indent); - } - } - - // bones. - // - // output structure: - // subset of node hierarchy that are "skeleton", - // i.e. do not have meshes but only bones. - // but.. i'm not sure how anyone could guarantee that... - // - // input... - // well, for each mesh it has "bones", - // and the bone names correspond to nodes. - // of course we also need the parent nodes, - // as they give some of the transform........ - // - // well. we can assume a sane input, i suppose. - // - // so input is the bone node hierarchy, - // with an extra thing for the transformation of the MESH in BONE space. - // - // output is a set of bone nodes, - // a "bindpose" which indicates the default local transform of all bones, - // and a set of "deformers". - // each deformer is parented to a mesh geometry, - // and has one or more "subdeformer"s as children. - // each subdeformer has one bone node as a child, - // and represents the influence of that bone on the grandparent mesh. - // the subdeformer has a list of indices, and weights, - // with indices specifying vertex indices, - // and weights specifying the corresponding influence of this bone. - // it also has Transform and TransformLink elements, - // specifying the transform of the MESH in BONE space, - // and the transformation of the BONE in WORLD space, - // likely in the bindpose. - // - // the input bone structure is different but similar, - // storing the number of weights for this bone, - // and an array of (vertex index, weight) pairs. - // - // one sticky point is that the number of vertices may not match, - // because assimp splits vertices by normal, uv, etc. - - // functor for aiNode sorting - struct SortNodeByName - { - bool operator()(const aiNode *lhs, const aiNode *rhs) const - { - return strcmp(lhs->mName.C_Str(), rhs->mName.C_Str()) < 0; - } - }; - - // first we should mark the skeleton for each mesh. - // the skeleton must include not only the aiBones, - // but also all their parent nodes. - // anything that affects the position of any bone node must be included. - // Use SorNodeByName to make sure the exported result will be the same across all systems - // Otherwise the aiNodes of the skeleton would be sorted based on the pointer address, which isn't consistent - std::vector<std::set<const aiNode*, SortNodeByName>> skeleton_by_mesh(mScene->mNumMeshes); - // at the same time we can build a list of all the skeleton nodes, - // which will be used later to mark them as type "limbNode". - std::unordered_set<const aiNode*> limbnodes; - - //actual bone nodes in fbx, without parenting-up - std::unordered_set<std::string> setAllBoneNamesInScene; - for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m) - { - aiMesh* pMesh = mScene->mMeshes[m]; - for(unsigned int b = 0; b < pMesh->mNumBones; ++ b) - setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data); - } - aiMatrix4x4 mxTransIdentity; - - // and a map of nodes by bone name, as finding them is annoying. - std::map<std::string,aiNode*> node_by_bone; - for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) { - const aiMesh* m = mScene->mMeshes[mi]; - std::set<const aiNode*, SortNodeByName> skeleton; - for (size_t bi =0; bi < m->mNumBones; ++bi) { - const aiBone* b = m->mBones[bi]; - const std::string name(b->mName.C_Str()); - auto elem = node_by_bone.find(name); - aiNode* n; - if (elem != node_by_bone.end()) { - n = elem->second; - } else { - n = mScene->mRootNode->FindNode(b->mName); - if (!n) { - // this should never happen - std::stringstream err; - err << "Failed to find node for bone: \"" << name << "\""; - throw DeadlyExportError(err.str()); - } - node_by_bone[name] = n; - limbnodes.insert(n); - } - skeleton.insert(n); - // mark all parent nodes as skeleton as well, - // up until we find the root node, - // or else the node containing the mesh, - // or else the parent of a node containig the mesh. - for ( - const aiNode* parent = n->mParent; - parent && parent != mScene->mRootNode; - parent = parent->mParent - ) { - // if we've already done this node we can skip it all - if (skeleton.count(parent)) { - break; - } - // ignore fbx transform nodes as these will be collapsed later - // TODO: cache this by aiNode* - const std::string node_name(parent->mName.C_Str()); - if (node_name.find(MAGIC_NODE_TAG) != std::string::npos) { - continue; - } - //not a bone in scene && no effect in transform - if(setAllBoneNamesInScene.find(node_name)==setAllBoneNamesInScene.end() - && parent->mTransformation == mxTransIdentity) { - continue; - } - // otherwise check if this is the root of the skeleton - bool end = false; - // is the mesh part of this node? - for (size_t i = 0; i < parent->mNumMeshes; ++i) { - if (parent->mMeshes[i] == mi) { - end = true; - break; - } - } - // is the mesh in one of the children of this node? - for (size_t j = 0; j < parent->mNumChildren; ++j) { - aiNode* child = parent->mChildren[j]; - for (size_t i = 0; i < child->mNumMeshes; ++i) { - if (child->mMeshes[i] == mi) { - end = true; - break; - } - } - if (end) { break; } - } - - // if it was the skeleton root we can finish here - if (end) { break; } - } - } - skeleton_by_mesh[mi] = skeleton; - } - - // we'll need the uids for the bone nodes, so generate them now - for (size_t i = 0; i < mScene->mNumMeshes; ++i) { - auto &s = skeleton_by_mesh[i]; - for (const aiNode* n : s) { - auto elem = node_uids.find(n); - if (elem == node_uids.end()) { - node_uids[n] = generate_uid(); - } - } - } - - // now, for each aiMesh, we need to export a deformer, - // and for each aiBone a subdeformer, - // which should have all the skinning info. - // these will need to be connected properly to the mesh, - // and we can do that all now. - for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) { - const aiMesh* m = mScene->mMeshes[mi]; - if (!m->HasBones()) { - continue; - } - // make a deformer for this mesh - int64_t deformer_uid = generate_uid(); - FBX::Node dnode("Deformer"); - dnode.AddProperties(deformer_uid, FBX::SEPARATOR + "Deformer", "Skin"); - dnode.AddChild("Version", int32_t(101)); - // "acuracy"... this is not a typo.... - dnode.AddChild("Link_DeformAcuracy", double(50)); - dnode.AddChild("SkinningType", "Linear"); // TODO: other modes? - dnode.Dump(outstream, binary, indent); - - // connect it - connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]); - - //computed before - std::vector<int32_t>& vertex_indices = vVertexIndice[mi]; - - // TODO, FIXME: this won't work if anything is not in the bind pose. - // for now if such a situation is detected, we throw an exception. - std::set<const aiBone*> not_in_bind_pose; - std::set<const aiNode*> no_offset_matrix; - - // first get this mesh's position in world space, - // as we'll need it for each subdeformer. - // - // ...of course taking the position of the MESH doesn't make sense, - // as it can be instanced to many nodes. - // All we can do is assume no instancing, - // and take the first node we find that contains the mesh. - aiNode* mesh_node = get_node_for_mesh((unsigned int)mi, mScene->mRootNode); - aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene); - - // now make a subdeformer for each bone in the skeleton - const std::set<const aiNode*, SortNodeByName> skeleton= skeleton_by_mesh[mi]; - for (const aiNode* bone_node : skeleton) { - // if there's a bone for this node, find it - const aiBone* b = nullptr; - for (size_t bi = 0; bi < m->mNumBones; ++bi) { - // TODO: this probably should index by something else - const std::string name(m->mBones[bi]->mName.C_Str()); - if (node_by_bone[name] == bone_node) { - b = m->mBones[bi]; - break; - } - } - if (!b) { - no_offset_matrix.insert(bone_node); - } - - // start the subdeformer node - const int64_t subdeformer_uid = generate_uid(); - FBX::Node sdnode("Deformer"); - sdnode.AddProperties( - subdeformer_uid, FBX::SEPARATOR + "SubDeformer", "Cluster" - ); - sdnode.AddChild("Version", int32_t(100)); - sdnode.AddChild("UserData", "", ""); - - // add indices and weights, if any - if (b) { - std::vector<int32_t> subdef_indices; - std::vector<double> subdef_weights; - int32_t last_index = -1; - for (size_t wi = 0; wi < b->mNumWeights; ++wi) { - int32_t vi = vertex_indices[b->mWeights[wi].mVertexId]; - if (vi == last_index) { - // only for vertices we exported to fbx - // TODO, FIXME: this assumes identically-located vertices - // will always deform in the same way. - // as assimp doesn't store a separate list of "positions", - // there's not much that can be done about this - // other than assuming that identical position means - // identical vertex. - continue; - } - subdef_indices.push_back(vi); - subdef_weights.push_back(b->mWeights[wi].mWeight); - last_index = vi; - } - // yes, "indexes" - sdnode.AddChild("Indexes", subdef_indices); - sdnode.AddChild("Weights", subdef_weights); - } - - // transform is the transform of the mesh, but in bone space. - // if the skeleton is in the bind pose, - // we can take the inverse of the world-space bone transform - // and multiply by the world-space transform of the mesh. - aiMatrix4x4 bone_xform = get_world_transform(bone_node, mScene); - aiMatrix4x4 inverse_bone_xform = bone_xform; - inverse_bone_xform.Inverse(); - aiMatrix4x4 tr = inverse_bone_xform * mesh_xform; - - sdnode.AddChild("Transform", tr); - - - sdnode.AddChild("TransformLink", bone_xform); - // note: this means we ALWAYS rely on the mesh node transform - // being unchanged from the time the skeleton was bound. - // there's not really any way around this at the moment. - - // done - sdnode.Dump(outstream, binary, indent); - - // lastly, connect to the parent deformer - connections.emplace_back( - "C", "OO", subdeformer_uid, deformer_uid - ); - - // we also need to connect the limb node to the subdeformer. - connections.emplace_back( - "C", "OO", node_uids[bone_node], subdeformer_uid - ); - } - - // if we cannot create a valid FBX file, simply die. - // this will both prevent unnecessary bug reports, - // and tell the user what they can do to fix the situation - // (i.e. export their model in the bind pose). - if (no_offset_matrix.size() && not_in_bind_pose.size()) { - std::stringstream err; - err << "Not enough information to construct bind pose"; - err << " for mesh " << mi << "!"; - err << " Transform matrix for bone \""; - err << (*not_in_bind_pose.begin())->mName.C_Str() << "\""; - if (not_in_bind_pose.size() > 1) { - err << " (and " << not_in_bind_pose.size() - 1 << " more)"; - } - err << " does not match mOffsetMatrix,"; - err << " and node \""; - err << (*no_offset_matrix.begin())->mName.C_Str() << "\""; - if (no_offset_matrix.size() > 1) { - err << " (and " << no_offset_matrix.size() - 1 << " more)"; - } - err << " has no offset matrix to rely on."; - err << " Please ensure bones are in the bind pose to export."; - throw DeadlyExportError(err.str()); - } - - } - - // BindPose - // - // This is a legacy system, which should be unnecessary. - // - // Somehow including it slows file loading by the official FBX SDK, - // and as it can reconstruct it from the deformers anyway, - // this is not currently included. - // - // The code is kept here in case it's useful in the future, - // but it's pretty much a hack anyway, - // as assimp doesn't store bindpose information for full skeletons. - // - /*for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) { - aiMesh* mesh = mScene->mMeshes[mi]; - if (! mesh->HasBones()) { continue; } - int64_t bindpose_uid = generate_uid(); - FBX::Node bpnode("Pose"); - bpnode.AddProperty(bindpose_uid); - // note: this uid is never linked or connected to anything. - bpnode.AddProperty(FBX::SEPARATOR + "Pose"); // blank name - bpnode.AddProperty("BindPose"); - - bpnode.AddChild("Type", "BindPose"); - bpnode.AddChild("Version", int32_t(100)); - - aiNode* mesh_node = get_node_for_mesh(mi, mScene->mRootNode); - - // next get the whole skeleton for this mesh. - // we need it all to define the bindpose section. - // the FBX SDK will complain if it's missing, - // and also if parents of used bones don't have a subdeformer. - // order shouldn't matter. - std::set<aiNode*> skeleton; - for (size_t bi = 0; bi < mesh->mNumBones; ++bi) { - // bone node should have already been indexed - const aiBone* b = mesh->mBones[bi]; - const std::string bone_name(b->mName.C_Str()); - aiNode* parent = node_by_bone[bone_name]; - // insert all nodes down to the root or mesh node - while ( - parent - && parent != mScene->mRootNode - && parent != mesh_node - ) { - skeleton.insert(parent); - parent = parent->mParent; - } - } - - // number of pose nodes. includes one for the mesh itself. - bpnode.AddChild("NbPoseNodes", int32_t(1 + skeleton.size())); - - // the first pose node is always the mesh itself - FBX::Node pose("PoseNode"); - pose.AddChild("Node", mesh_uids[mi]); - aiMatrix4x4 mesh_node_xform = get_world_transform(mesh_node, mScene); - pose.AddChild("Matrix", mesh_node_xform); - bpnode.AddChild(pose); - - for (aiNode* bonenode : skeleton) { - // does this node have a uid yet? - int64_t node_uid; - auto node_uid_iter = node_uids.find(bonenode); - if (node_uid_iter != node_uids.end()) { - node_uid = node_uid_iter->second; - } else { - node_uid = generate_uid(); - node_uids[bonenode] = node_uid; - } - - // make a pose thingy - pose = FBX::Node("PoseNode"); - pose.AddChild("Node", node_uid); - aiMatrix4x4 node_xform = get_world_transform(bonenode, mScene); - pose.AddChild("Matrix", node_xform); - bpnode.AddChild(pose); - } - - // now write it - bpnode.Dump(outstream, binary, indent); - }*/ - - // TODO: cameras, lights - - // write nodes (i.e. model hierarchy) - // start at root node - WriteModelNodes( - outstream, mScene->mRootNode, 0, limbnodes - ); - - // animations - // - // in FBX there are: - // * AnimationStack - corresponds to an aiAnimation - // * AnimationLayer - a combinable animation component - // * AnimationCurveNode - links the property to be animated - // * AnimationCurve - defines animation data for a single property value - // - // the CurveNode also provides the default value for a property, - // such as the X, Y, Z coordinates for animatable translation. - // - // the Curve only specifies values for one component of the property, - // so there will be a separate AnimationCurve for X, Y, and Z. - // - // Assimp has: - // * aiAnimation - basically corresponds to an AnimationStack - // * aiNodeAnim - defines all animation for one aiNode - // * aiVectorKey/aiQuatKey - define the keyframe data for T/R/S - // - // assimp has no equivalent for AnimationLayer, - // and these are flattened on FBX import. - // we can assume there will be one per AnimationStack. - // - // the aiNodeAnim contains all animation data for a single aiNode, - // which will correspond to three AnimationCurveNode's: - // one each for translation, rotation and scale. - // The data for each of these will be put in 9 AnimationCurve's, - // T.X, T.Y, T.Z, R.X, R.Y, R.Z, etc. - - // AnimationStack / aiAnimation - std::vector<int64_t> animation_stack_uids(mScene->mNumAnimations); - for (size_t ai = 0; ai < mScene->mNumAnimations; ++ai) { - int64_t animstack_uid = generate_uid(); - animation_stack_uids[ai] = animstack_uid; - const aiAnimation* anim = mScene->mAnimations[ai]; - - FBX::Node asnode("AnimationStack"); - std::string name = anim->mName.C_Str() + FBX::SEPARATOR + "AnimStack"; - asnode.AddProperties(animstack_uid, name, ""); - FBX::Node p("Properties70"); - p.AddP70time("LocalStart", 0); // assimp doesn't store this - p.AddP70time("LocalStop", to_ktime(anim->mDuration, anim)); - p.AddP70time("ReferenceStart", 0); - p.AddP70time("ReferenceStop", to_ktime(anim->mDuration, anim)); - asnode.AddChild(p); - - // this node absurdly always pretends it has children - // (in this case it does, but just in case...) - asnode.force_has_children = true; - asnode.Dump(outstream, binary, indent); - - // note: animation stacks are not connected to anything - } - - // AnimationLayer - one per aiAnimation - std::vector<int64_t> animation_layer_uids(mScene->mNumAnimations); - for (size_t ai = 0; ai < mScene->mNumAnimations; ++ai) { - int64_t animlayer_uid = generate_uid(); - animation_layer_uids[ai] = animlayer_uid; - FBX::Node alnode("AnimationLayer"); - alnode.AddProperties(animlayer_uid, FBX::SEPARATOR + "AnimLayer", ""); - - // this node absurdly always pretends it has children - alnode.force_has_children = true; - alnode.Dump(outstream, binary, indent); - - // connect to the relevant animstack - connections.emplace_back( - "C", "OO", animlayer_uid, animation_stack_uids[ai] - ); - } - - // AnimCurveNode - three per aiNodeAnim - std::vector<std::vector<std::array<int64_t,3>>> curve_node_uids; - for (size_t ai = 0; ai < mScene->mNumAnimations; ++ai) { - const aiAnimation* anim = mScene->mAnimations[ai]; - const int64_t layer_uid = animation_layer_uids[ai]; - std::vector<std::array<int64_t,3>> nodeanim_uids; - for (size_t nai = 0; nai < anim->mNumChannels; ++nai) { - const aiNodeAnim* na = anim->mChannels[nai]; - // get the corresponding aiNode - const aiNode* node = mScene->mRootNode->FindNode(na->mNodeName); - // and its transform - const aiMatrix4x4 node_xfm = get_world_transform(node, mScene); - aiVector3D T, R, S; - node_xfm.Decompose(S, R, T); - - // AnimationCurveNode uids - std::array<int64_t,3> ids; - ids[0] = generate_uid(); // T - ids[1] = generate_uid(); // R - ids[2] = generate_uid(); // S - - // translation - WriteAnimationCurveNode(outstream, - ids[0], "T", T, "Lcl Translation", - layer_uid, node_uids[node] - ); - - // rotation - WriteAnimationCurveNode(outstream, - ids[1], "R", R, "Lcl Rotation", - layer_uid, node_uids[node] - ); - - // scale - WriteAnimationCurveNode(outstream, - ids[2], "S", S, "Lcl Scale", - layer_uid, node_uids[node] - ); - - // store the uids for later use - nodeanim_uids.push_back(ids); - } - curve_node_uids.push_back(nodeanim_uids); - } - - // AnimCurve - defines actual keyframe data. - // there's a separate curve for every component of every vector, - // for example a transform curvenode will have separate X/Y/Z AnimCurve's - for (size_t ai = 0; ai < mScene->mNumAnimations; ++ai) { - const aiAnimation* anim = mScene->mAnimations[ai]; - for (size_t nai = 0; nai < anim->mNumChannels; ++nai) { - const aiNodeAnim* na = anim->mChannels[nai]; - // get the corresponding aiNode - const aiNode* node = mScene->mRootNode->FindNode(na->mNodeName); - // and its transform - const aiMatrix4x4 node_xfm = get_world_transform(node, mScene); - aiVector3D T, R, S; - node_xfm.Decompose(S, R, T); - const std::array<int64_t,3>& ids = curve_node_uids[ai][nai]; - - std::vector<int64_t> times; - std::vector<float> xval, yval, zval; - - // position/translation - for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) { - const aiVectorKey& k = na->mPositionKeys[ki]; - times.push_back(to_ktime(k.mTime)); - xval.push_back(k.mValue.x); - yval.push_back(k.mValue.y); - zval.push_back(k.mValue.z); - } - // one curve each for X, Y, Z - WriteAnimationCurve(outstream, T.x, times, xval, ids[0], "d|X"); - WriteAnimationCurve(outstream, T.y, times, yval, ids[0], "d|Y"); - WriteAnimationCurve(outstream, T.z, times, zval, ids[0], "d|Z"); - - // rotation - times.clear(); xval.clear(); yval.clear(); zval.clear(); - for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) { - const aiQuatKey& k = na->mRotationKeys[ki]; - times.push_back(to_ktime(k.mTime)); - // TODO: aiQuaternion method to convert to Euler... - aiMatrix4x4 m(k.mValue.GetMatrix()); - aiVector3D qs, qr, qt; - m.Decompose(qs, qr, qt); - qr *= DEG; - xval.push_back(qr.x); - yval.push_back(qr.y); - zval.push_back(qr.z); - } - WriteAnimationCurve(outstream, R.x, times, xval, ids[1], "d|X"); - WriteAnimationCurve(outstream, R.y, times, yval, ids[1], "d|Y"); - WriteAnimationCurve(outstream, R.z, times, zval, ids[1], "d|Z"); - - // scaling/scale - times.clear(); xval.clear(); yval.clear(); zval.clear(); - for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) { - const aiVectorKey& k = na->mScalingKeys[ki]; - times.push_back(to_ktime(k.mTime)); - xval.push_back(k.mValue.x); - yval.push_back(k.mValue.y); - zval.push_back(k.mValue.z); - } - WriteAnimationCurve(outstream, S.x, times, xval, ids[2], "d|X"); - WriteAnimationCurve(outstream, S.y, times, yval, ids[2], "d|Y"); - WriteAnimationCurve(outstream, S.z, times, zval, ids[2], "d|Z"); - } - } - - indent = 0; - object_node.End(outstream, binary, indent, true); -} - -// convenience map of magic node name strings to FBX properties, -// including the expected type of transform. -const std::map<std::string,std::pair<std::string,char>> transform_types = { - {"Translation", {"Lcl Translation", 't'}}, - {"RotationOffset", {"RotationOffset", 't'}}, - {"RotationPivot", {"RotationPivot", 't'}}, - {"PreRotation", {"PreRotation", 'r'}}, - {"Rotation", {"Lcl Rotation", 'r'}}, - {"PostRotation", {"PostRotation", 'r'}}, - {"RotationPivotInverse", {"RotationPivotInverse", 'i'}}, - {"ScalingOffset", {"ScalingOffset", 't'}}, - {"ScalingPivot", {"ScalingPivot", 't'}}, - {"Scaling", {"Lcl Scaling", 's'}}, - {"ScalingPivotInverse", {"ScalingPivotInverse", 'i'}}, - {"GeometricScaling", {"GeometricScaling", 's'}}, - {"GeometricRotation", {"GeometricRotation", 'r'}}, - {"GeometricTranslation", {"GeometricTranslation", 't'}}, - {"GeometricTranslationInverse", {"GeometricTranslationInverse", 'i'}}, - {"GeometricRotationInverse", {"GeometricRotationInverse", 'i'}}, - {"GeometricScalingInverse", {"GeometricScalingInverse", 'i'}} -}; - -// write a single model node to the stream -void FBXExporter::WriteModelNode( - StreamWriterLE& outstream, - bool binary, - const aiNode* node, - int64_t node_uid, - const std::string& type, - const std::vector<std::pair<std::string,aiVector3D>>& transform_chain, - TransformInheritance inherit_type -){ - const aiVector3D zero = {0, 0, 0}; - const aiVector3D one = {1, 1, 1}; - FBX::Node m("Model"); - std::string name = node->mName.C_Str() + FBX::SEPARATOR + "Model"; - m.AddProperties(node_uid, name, type); - m.AddChild("Version", int32_t(232)); - FBX::Node p("Properties70"); - p.AddP70bool("RotationActive", 1); - p.AddP70int("DefaultAttributeIndex", 0); - p.AddP70enum("InheritType", inherit_type); - if (transform_chain.empty()) { - // decompose 4x4 transform matrix into TRS - aiVector3D t, r, s; - node->mTransformation.Decompose(s, r, t); - if (t != zero) { - p.AddP70( - "Lcl Translation", "Lcl Translation", "", "A", - double(t.x), double(t.y), double(t.z) - ); - } - if (r != zero) { - p.AddP70( - "Lcl Rotation", "Lcl Rotation", "", "A", - double(DEG*r.x), double(DEG*r.y), double(DEG*r.z) - ); - } - if (s != one) { - p.AddP70( - "Lcl Scaling", "Lcl Scaling", "", "A", - double(s.x), double(s.y), double(s.z) - ); - } - } else { - // apply the transformation chain. - // these transformation elements are created when importing FBX, - // which has a complex transformation hierarchy for each node. - // as such we can bake the hierarchy back into the node on export. - for (auto &item : transform_chain) { - auto elem = transform_types.find(item.first); - if (elem == transform_types.end()) { - // then this is a bug - std::stringstream err; - err << "unrecognized FBX transformation type: "; - err << item.first; - throw DeadlyExportError(err.str()); - } - const std::string &name = elem->second.first; - const aiVector3D &v = item.second; - if (name.compare(0, 4, "Lcl ") == 0) { - // special handling for animatable properties - p.AddP70( - name, name, "", "A", - double(v.x), double(v.y), double(v.z) - ); - } else { - p.AddP70vector(name, v.x, v.y, v.z); - } - } - } - m.AddChild(p); - - // not sure what these are for, - // but they seem to be omnipresent - m.AddChild("Shading", FBXExportProperty(true)); - m.AddChild("Culling", FBXExportProperty("CullingOff")); - - m.Dump(outstream, binary, 1); -} - -// wrapper for WriteModelNodes to create and pass a blank transform chain -void FBXExporter::WriteModelNodes( - StreamWriterLE& s, - const aiNode* node, - int64_t parent_uid, - const std::unordered_set<const aiNode*>& limbnodes -) { - std::vector<std::pair<std::string,aiVector3D>> chain; - WriteModelNodes(s, node, parent_uid, limbnodes, chain); -} - -void FBXExporter::WriteModelNodes( - StreamWriterLE& outstream, - const aiNode* node, - int64_t parent_uid, - const std::unordered_set<const aiNode*>& limbnodes, - std::vector<std::pair<std::string,aiVector3D>>& transform_chain -) { - // first collapse any expanded transformation chains created by FBX import. - std::string node_name(node->mName.C_Str()); - if (node_name.find(MAGIC_NODE_TAG) != std::string::npos) { - auto pos = node_name.find(MAGIC_NODE_TAG) + MAGIC_NODE_TAG.size() + 1; - std::string type_name = node_name.substr(pos); - auto elem = transform_types.find(type_name); - if (elem == transform_types.end()) { - // then this is a bug and should be fixed - std::stringstream err; - err << "unrecognized FBX transformation node"; - err << " of type " << type_name << " in node " << node_name; - throw DeadlyExportError(err.str()); - } - aiVector3D t, r, s; - node->mTransformation.Decompose(s, r, t); - switch (elem->second.second) { - case 'i': // inverse - // we don't need to worry about the inverse matrices - break; - case 't': // translation - transform_chain.emplace_back(elem->first, t); - break; - case 'r': // rotation - r *= float(DEG); - transform_chain.emplace_back(elem->first, r); - break; - case 's': // scale - transform_chain.emplace_back(elem->first, s); - break; - default: - // this should never happen - std::stringstream err; - err << "unrecognized FBX transformation type code: "; - err << elem->second.second; - throw DeadlyExportError(err.str()); - } - // now continue on to any child nodes - for (unsigned i = 0; i < node->mNumChildren; ++i) { - WriteModelNodes( - outstream, - node->mChildren[i], - parent_uid, - limbnodes, - transform_chain - ); - } - return; - } - - int64_t node_uid = 0; - // generate uid and connect to parent, if not the root node, - if (node != mScene->mRootNode) { - auto elem = node_uids.find(node); - if (elem != node_uids.end()) { - node_uid = elem->second; - } else { - node_uid = generate_uid(); - node_uids[node] = node_uid; - } - connections.emplace_back("C", "OO", node_uid, parent_uid); - } - - // what type of node is this? - if (node == mScene->mRootNode) { - // handled later - } else if (node->mNumMeshes == 1) { - // connect to child mesh, which should have been written previously - connections.emplace_back( - "C", "OO", mesh_uids[node->mMeshes[0]], node_uid - ); - // also connect to the material for the child mesh - connections.emplace_back( - "C", "OO", - material_uids[mScene->mMeshes[node->mMeshes[0]]->mMaterialIndex], - node_uid - ); - // write model node - WriteModelNode( - outstream, binary, node, node_uid, "Mesh", transform_chain - ); - } else if (limbnodes.count(node)) { - WriteModelNode( - outstream, binary, node, node_uid, "LimbNode", transform_chain - ); - // we also need to write a nodeattribute to mark it as a skeleton - int64_t node_attribute_uid = generate_uid(); - FBX::Node na("NodeAttribute"); - na.AddProperties( - node_attribute_uid, FBX::SEPARATOR + "NodeAttribute", "LimbNode" - ); - na.AddChild("TypeFlags", FBXExportProperty("Skeleton")); - na.Dump(outstream, binary, 1); - // and connect them - connections.emplace_back("C", "OO", node_attribute_uid, node_uid); - } else { - // generate a null node so we can add children to it - WriteModelNode( - outstream, binary, node, node_uid, "Null", transform_chain - ); - } - - // if more than one child mesh, make nodes for each mesh - if (node->mNumMeshes > 1 || node == mScene->mRootNode) { - for (size_t i = 0; i < node->mNumMeshes; ++i) { - // make a new model node - int64_t new_node_uid = generate_uid(); - // connect to parent node - connections.emplace_back("C", "OO", new_node_uid, node_uid); - // connect to child mesh, which should have been written previously - connections.emplace_back( - "C", "OO", mesh_uids[node->mMeshes[i]], new_node_uid - ); - // also connect to the material for the child mesh - connections.emplace_back( - "C", "OO", - material_uids[ - mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex - ], - new_node_uid - ); - // write model node - FBX::Node m("Model"); - // take name from mesh name, if it exists - std::string name = mScene->mMeshes[node->mMeshes[i]]->mName.C_Str(); - name += FBX::SEPARATOR + "Model"; - m.AddProperties(new_node_uid, name, "Mesh"); - m.AddChild("Version", int32_t(232)); - FBX::Node p("Properties70"); - p.AddP70enum("InheritType", 1); - m.AddChild(p); - m.Dump(outstream, binary, 1); - } - } - - // now recurse into children - for (size_t i = 0; i < node->mNumChildren; ++i) { - WriteModelNodes( - outstream, node->mChildren[i], node_uid, limbnodes - ); - } -} - - -void FBXExporter::WriteAnimationCurveNode( - StreamWriterLE& outstream, - int64_t uid, - const std::string& name, // "T", "R", or "S" - aiVector3D default_value, - std::string property_name, // "Lcl Translation" etc - int64_t layer_uid, - int64_t node_uid -) { - FBX::Node n("AnimationCurveNode"); - n.AddProperties(uid, name + FBX::SEPARATOR + "AnimCurveNode", ""); - FBX::Node p("Properties70"); - p.AddP70numberA("d|X", default_value.x); - p.AddP70numberA("d|Y", default_value.y); - p.AddP70numberA("d|Z", default_value.z); - n.AddChild(p); - n.Dump(outstream, binary, 1); - // connect to layer - this->connections.emplace_back("C", "OO", uid, layer_uid); - // connect to bone - this->connections.emplace_back("C", "OP", uid, node_uid, property_name); -} - - -void FBXExporter::WriteAnimationCurve( - StreamWriterLE& outstream, - double default_value, - const std::vector<int64_t>& times, - const std::vector<float>& values, - int64_t curvenode_uid, - const std::string& property_link // "d|X", "d|Y", etc -) { - FBX::Node n("AnimationCurve"); - int64_t curve_uid = generate_uid(); - n.AddProperties(curve_uid, FBX::SEPARATOR + "AnimCurve", ""); - n.AddChild("Default", default_value); - n.AddChild("KeyVer", int32_t(4009)); - n.AddChild("KeyTime", times); - n.AddChild("KeyValueFloat", values); - // TODO: keyattr flags and data (STUB for now) - n.AddChild("KeyAttrFlags", std::vector<int32_t>{0}); - n.AddChild("KeyAttrDataFloat", std::vector<float>{0,0,0,0}); - n.AddChild( - "KeyAttrRefCount", - std::vector<int32_t>{static_cast<int32_t>(times.size())} - ); - n.Dump(outstream, binary, 1); - this->connections.emplace_back( - "C", "OP", curve_uid, curvenode_uid, property_link - ); -} - - -void FBXExporter::WriteConnections () -{ - // we should have completed the connection graph already, - // so basically just dump it here - if (!binary) { - WriteAsciiSectionHeader("Object connections"); - } - // TODO: comments with names in the ascii version - FBX::Node conn("Connections"); - StreamWriterLE outstream(outfile); - conn.Begin(outstream, binary, 0); - conn.BeginChildren(outstream, binary, 0); - for (auto &n : connections) { - n.Dump(outstream, binary, 1); - } - conn.End(outstream, binary, 0, !connections.empty()); - connections.clear(); -} - -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER -#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/thirdparty/assimp/code/FBX/FBXExporter.h b/thirdparty/assimp/code/FBX/FBXExporter.h deleted file mode 100644 index 1ae727eda9..0000000000 --- a/thirdparty/assimp/code/FBX/FBXExporter.h +++ /dev/null @@ -1,178 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXExporter.h -* Declares the exporter class to write a scene to an fbx file -*/ -#ifndef AI_FBXEXPORTER_H_INC -#define AI_FBXEXPORTER_H_INC - -#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - -#include "FBXExportNode.h" // FBX::Node -#include "FBXCommon.h" // FBX::TransformInheritance - -#include <assimp/types.h> -//#include <assimp/material.h> -#include <assimp/StreamWriter.h> // StreamWriterLE -#include <assimp/Exceptional.h> // DeadlyExportError - -#include <vector> -#include <map> -#include <unordered_set> -#include <memory> // shared_ptr -#include <sstream> // stringstream - -struct aiScene; -struct aiNode; -//struct aiMaterial; - -namespace Assimp -{ - class IOSystem; - class IOStream; - class ExportProperties; - - // --------------------------------------------------------------------- - /** Helper class to export a given scene to an FBX file. */ - // --------------------------------------------------------------------- - class FBXExporter - { - public: - /// Constructor for a specific scene to export - FBXExporter(const aiScene* pScene, const ExportProperties* pProperties); - - // call one of these methods to export - void ExportBinary(const char* pFile, IOSystem* pIOSystem); - void ExportAscii(const char* pFile, IOSystem* pIOSystem); - - private: - bool binary; // whether current export is in binary or ascii format - const aiScene* mScene; // the scene to export - const ExportProperties* mProperties; // currently unused - std::shared_ptr<IOStream> outfile; // file to write to - - std::vector<FBX::Node> connections; // connection storage - - std::vector<int64_t> mesh_uids; - std::vector<int64_t> material_uids; - std::map<const aiNode*,int64_t> node_uids; - - // this crude unique-ID system is actually fine - int64_t last_uid = 999999; - int64_t generate_uid() { return ++last_uid; } - - // binary files have a specific header and footer, - // in addition to the actual data - void WriteBinaryHeader(); - void WriteBinaryFooter(); - - // ascii files have a comment at the top - void WriteAsciiHeader(); - - // WriteAllNodes does the actual export. - // It just calls all the Write<Section> methods below in order. - void WriteAllNodes(); - - // Methods to write individual sections. - // The order here matches the order inside an FBX file. - // Each method corresponds to a top-level FBX section, - // except WriteHeader which also includes some binary-only sections - // and WriteFooter which is binary data only. - void WriteHeaderExtension(); - // WriteFileId(); // binary-only, included in WriteHeader - // WriteCreationTime(); // binary-only, included in WriteHeader - // WriteCreator(); // binary-only, included in WriteHeader - void WriteGlobalSettings(); - void WriteDocuments(); - void WriteReferences(); - void WriteDefinitions(); - void WriteObjects(); - void WriteConnections(); - // WriteTakes(); // deprecated since at least 2015 (fbx 7.4) - - // helpers - void WriteAsciiSectionHeader(const std::string& title); - void WriteModelNodes( - Assimp::StreamWriterLE& s, - const aiNode* node, - int64_t parent_uid, - const std::unordered_set<const aiNode*>& limbnodes - ); - void WriteModelNodes( // usually don't call this directly - StreamWriterLE& s, - const aiNode* node, - int64_t parent_uid, - const std::unordered_set<const aiNode*>& limbnodes, - std::vector<std::pair<std::string,aiVector3D>>& transform_chain - ); - void WriteModelNode( // nor this - StreamWriterLE& s, - bool binary, - const aiNode* node, - int64_t node_uid, - const std::string& type, - const std::vector<std::pair<std::string,aiVector3D>>& xfm_chain, - FBX::TransformInheritance ti_type=FBX::TransformInheritance_RSrs - ); - void WriteAnimationCurveNode( - StreamWriterLE& outstream, - int64_t uid, - const std::string& name, // "T", "R", or "S" - aiVector3D default_value, - std::string property_name, // "Lcl Translation" etc - int64_t animation_layer_uid, - int64_t node_uid - ); - void WriteAnimationCurve( - StreamWriterLE& outstream, - double default_value, - const std::vector<int64_t>& times, - const std::vector<float>& values, - int64_t curvenode_id, - const std::string& property_link // "d|X", "d|Y", etc - ); - }; -} - -#endif // ASSIMP_BUILD_NO_FBX_EXPORTER - -#endif // AI_FBXEXPORTER_H_INC diff --git a/thirdparty/assimp/code/FBX/FBXImportSettings.h b/thirdparty/assimp/code/FBX/FBXImportSettings.h deleted file mode 100644 index 1a4c80f8b2..0000000000 --- a/thirdparty/assimp/code/FBX/FBXImportSettings.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXImportSettings.h - * @brief FBX importer runtime configuration - */ -#ifndef INCLUDED_AI_FBX_IMPORTSETTINGS_H -#define INCLUDED_AI_FBX_IMPORTSETTINGS_H - -namespace Assimp { -namespace FBX { - -/** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */ -struct ImportSettings -{ - ImportSettings() - : strictMode(true) - , readAllLayers(true) - , readAllMaterials(false) - , readMaterials(true) - , readTextures(true) - , readCameras(true) - , readLights(true) - , readAnimations(true) - , readWeights(true) - , preservePivots(true) - , optimizeEmptyAnimationCurves(true) - , useLegacyEmbeddedTextureNaming(false) - , removeEmptyBones( true ) - , convertToMeters( false ) { - // empty - } - - - /** enable strict mode: - * - only accept fbx 2012, 2013 files - * - on the slightest error, give up. - * - * Basically, strict mode means that the fbx file will actually - * be validated. Strict mode is off by default. */ - bool strictMode; - - /** specifies whether all geometry layers are read and scanned for - * usable data channels. The FBX spec indicates that many readers - * will only read the first channel and that this is in some way - * the recommended way- in reality, however, it happens a lot that - * vertex data is spread among multiple layers. The default - * value for this option is true.*/ - bool readAllLayers; - - /** specifies whether all materials are read, or only those that - * are referenced by at least one mesh. Reading all materials - * may make FBX reading a lot slower since all objects - * need to be processed . - * This bit is ignored unless readMaterials=true*/ - bool readAllMaterials; - - - /** import materials (true) or skip them and assign a default - * material. The default value is true.*/ - bool readMaterials; - - /** import embedded textures? Default value is true.*/ - bool readTextures; - - /** import cameras? Default value is true.*/ - bool readCameras; - - /** import light sources? Default value is true.*/ - bool readLights; - - /** import animations (i.e. animation curves, the node - * skeleton is always imported). Default value is true. */ - bool readAnimations; - - /** read bones (vertex weights and deform info). - * Default value is true. */ - bool readWeights; - - /** preserve transformation pivots and offsets. Since these can - * not directly be represented in assimp, additional dummy - * nodes will be generated. Note that settings this to false - * can make animation import a lot slower. The default value - * is true. - * - * The naming scheme for the generated nodes is: - * <OriginalName>_$AssimpFbx$_<TransformName> - * - * where <TransformName> is one of - * RotationPivot - * RotationOffset - * PreRotation - * PostRotation - * ScalingPivot - * ScalingOffset - * Translation - * Scaling - * Rotation - **/ - bool preservePivots; - - /** do not import animation curves that specify a constant - * values matching the corresponding node transformation. - * The default value is true. */ - bool optimizeEmptyAnimationCurves; - - /** use legacy naming for embedded textures eg: (*0, *1, *2) - */ - bool useLegacyEmbeddedTextureNaming; - - /** Empty bones shall be removed - */ - bool removeEmptyBones; - - /** Set to true to perform a conversion from cm to meter after the import - */ - bool convertToMeters; -}; - - -} // !FBX -} // !Assimp - -#endif - diff --git a/thirdparty/assimp/code/FBX/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp deleted file mode 100644 index afcc1ddc78..0000000000 --- a/thirdparty/assimp/code/FBX/FBXImporter.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. -r -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXImporter.cpp - * @brief Implementation of the FBX importer. - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXImporter.h" - -#include "FBXConverter.h" -#include "FBXDocument.h" -#include "FBXParser.h" -#include "FBXTokenizer.h" -#include "FBXUtil.h" - -#include <assimp/MemoryIOWrapper.h> -#include <assimp/StreamReader.h> -#include <assimp/importerdesc.h> -#include <assimp/Importer.hpp> - -namespace Assimp { - -template <> -const char *LogFunctions<FBXImporter>::Prefix() { - static auto prefix = "FBX: "; - return prefix; -} - -} // namespace Assimp - -using namespace Assimp; -using namespace Assimp::Formatter; -using namespace Assimp::FBX; - -namespace { - -static const aiImporterDesc desc = { - "Autodesk FBX Importer", - "", - "", - "", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "fbx" -}; -} - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by #Importer -FBXImporter::FBXImporter() { -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FBXImporter::~FBXImporter() { -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool FBXImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { - const std::string &extension = GetExtension(pFile); - if (extension == std::string(desc.mFileExtensions)) { - return true; - } - - else if ((!extension.length() || checkSig) && pIOHandler) { - // at least ASCII-FBX files usually have a 'FBX' somewhere in their head - const char *tokens[] = { "fbx" }; - return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -// List all extensions handled by this loader -const aiImporterDesc *FBXImporter::GetInfo() const { - return &desc; -} - -// ------------------------------------------------------------------------------------------------ -// Setup configuration properties for the loader -void FBXImporter::SetupProperties(const Importer *pImp) { - settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true); - settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false); - settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true); - settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true); - settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true); - settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true); - settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true); - settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); - settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); - settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); - settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false); - settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true); - settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false); -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb")); - if (!stream) { - ThrowException("Could not open file for reading"); - } - - // read entire file into memory - no streaming for this, fbx - // files can grow large, but the assimp output data structure - // then becomes very large, too. Assimp doesn't support - // streaming for its output data structures so the net win with - // streaming input data would be very low. - std::vector<char> contents; - contents.resize(stream->FileSize() + 1); - stream->Read(&*contents.begin(), 1, contents.size() - 1); - contents[contents.size() - 1] = 0; - const char *const begin = &*contents.begin(); - - // broadphase tokenizing pass in which we identify the core - // syntax elements of FBX (brackets, commas, key:value mappings) - TokenList tokens; - try { - - bool is_binary = false; - if (!strncmp(begin, "Kaydara FBX Binary", 18)) { - is_binary = true; - TokenizeBinary(tokens, begin, contents.size()); - } else { - Tokenize(tokens, begin); - } - - // use this information to construct a very rudimentary - // parse-tree representing the FBX scope structure - Parser parser(tokens, is_binary); - - // take the raw parse-tree and convert it to a FBX DOM - Document doc(parser, settings); - - // convert the FBX DOM to aiScene - ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones); - - // size relative to cm - float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); - - // Set FBX file scale is relative to CM must be converted to M for - // assimp universal format (M) - SetFileScale(size_relative_to_cm * 0.01f); - - std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>()); - } catch (std::exception &) { - std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>()); - throw; - } -} - -#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER diff --git a/thirdparty/assimp/code/FBX/FBXImporter.h b/thirdparty/assimp/code/FBX/FBXImporter.h deleted file mode 100644 index c365b2cddf..0000000000 --- a/thirdparty/assimp/code/FBX/FBXImporter.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXImporter.h - * @brief Declaration of the FBX main importer class - */ -#ifndef INCLUDED_AI_FBX_IMPORTER_H -#define INCLUDED_AI_FBX_IMPORTER_H - -#include <assimp/BaseImporter.h> -#include <assimp/LogAux.h> - -#include "FBXImportSettings.h" - -namespace Assimp { - -// TinyFormatter.h -namespace Formatter { - template <typename T,typename TR, typename A> class basic_formatter; - typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; -} - -// ------------------------------------------------------------------------------------------- -/** Load the Autodesk FBX file format. - - See http://en.wikipedia.org/wiki/FBX -*/ -// ------------------------------------------------------------------------------------------- -class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> -{ -public: - FBXImporter(); - virtual ~FBXImporter(); - - // -------------------- - bool CanRead( const std::string& pFile, - IOSystem* pIOHandler, - bool checkSig - ) const; - -protected: - - // -------------------- - const aiImporterDesc* GetInfo () const; - - // -------------------- - void SetupProperties(const Importer* pImp); - - // -------------------- - void InternReadFile( const std::string& pFile, - aiScene* pScene, - IOSystem* pIOHandler - ); - -private: - FBX::ImportSettings settings; -}; // !class FBXImporter - -} // end of namespace Assimp -#endif // !INCLUDED_AI_FBX_IMPORTER_H - diff --git a/thirdparty/assimp/code/FBX/FBXMaterial.cpp b/thirdparty/assimp/code/FBX/FBXMaterial.cpp deleted file mode 100644 index f43a8b84b0..0000000000 --- a/thirdparty/assimp/code/FBX/FBXMaterial.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXMaterial.cpp - * @brief Assimp::FBX::Material and Assimp::FBX::Texture implementation - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXParser.h" -#include "FBXDocument.h" -#include "FBXImporter.h" -#include "FBXImportSettings.h" -#include "FBXDocumentUtil.h" -#include "FBXProperties.h" -#include <assimp/ByteSwapper.h> - -#include <algorithm> // std::transform -#include "FBXUtil.h" - -namespace Assimp { -namespace FBX { - - using namespace Util; - -// ------------------------------------------------------------------------------------------------ -Material::Material(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: Object(id,element,name) -{ - const Scope& sc = GetRequiredScope(element); - - const Element* const ShadingModel = sc["ShadingModel"]; - const Element* const MultiLayer = sc["MultiLayer"]; - - if(MultiLayer) { - multilayer = !!ParseTokenAsInt(GetRequiredToken(*MultiLayer,0)); - } - - if(ShadingModel) { - shading = ParseTokenAsString(GetRequiredToken(*ShadingModel,0)); - } - else { - DOMWarning("shading mode not specified, assuming phong",&element); - shading = "phong"; - } - - std::string templateName; - - // lower-case shading because Blender (for example) writes "Phong" - std::transform(shading.begin(), shading.end(), shading.begin(), ::tolower); - if(shading == "phong") { - templateName = "Material.FbxSurfacePhong"; - } - else if(shading == "lambert") { - templateName = "Material.FbxSurfaceLambert"; - } - else { - DOMWarning("shading mode not recognized: " + shading,&element); - } - - props = GetPropertyTable(doc,templateName,element,sc); - - // resolve texture links - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID()); - for(const Connection* con : conns) { - - // texture link to properties, not objects - if (!con->PropertyName().length()) { - continue; - } - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for texture link, ignoring",&element); - continue; - } - - const Texture* const tex = dynamic_cast<const Texture*>(ob); - if(!tex) { - const LayeredTexture* const layeredTexture = dynamic_cast<const LayeredTexture*>(ob); - if(!layeredTexture) { - DOMWarning("source object for texture link is not a texture or layered texture, ignoring",&element); - continue; - } - const std::string& prop = con->PropertyName(); - if (layeredTextures.find(prop) != layeredTextures.end()) { - DOMWarning("duplicate layered texture link: " + prop,&element); - } - - layeredTextures[prop] = layeredTexture; - ((LayeredTexture*)layeredTexture)->fillTexture(doc); - } - else - { - const std::string& prop = con->PropertyName(); - if (textures.find(prop) != textures.end()) { - DOMWarning("duplicate texture link: " + prop,&element); - } - - textures[prop] = tex; - } - - } -} - - -// ------------------------------------------------------------------------------------------------ -Material::~Material() -{ -} - - -// ------------------------------------------------------------------------------------------------ -Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: Object(id,element,name) -, uvScaling(1.0f,1.0f) -, media(0) -{ - const Scope& sc = GetRequiredScope(element); - - const Element* const Type = sc["Type"]; - const Element* const FileName = sc["FileName"]; - const Element* const RelativeFilename = sc["RelativeFilename"]; - const Element* const ModelUVTranslation = sc["ModelUVTranslation"]; - const Element* const ModelUVScaling = sc["ModelUVScaling"]; - const Element* const Texture_Alpha_Source = sc["Texture_Alpha_Source"]; - const Element* const Cropping = sc["Cropping"]; - - if(Type) { - type = ParseTokenAsString(GetRequiredToken(*Type,0)); - } - - if(FileName) { - fileName = ParseTokenAsString(GetRequiredToken(*FileName,0)); - } - - if(RelativeFilename) { - relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0)); - } - - if(ModelUVTranslation) { - uvTrans = aiVector2D(ParseTokenAsFloat(GetRequiredToken(*ModelUVTranslation,0)), - ParseTokenAsFloat(GetRequiredToken(*ModelUVTranslation,1)) - ); - } - - if(ModelUVScaling) { - uvScaling = aiVector2D(ParseTokenAsFloat(GetRequiredToken(*ModelUVScaling,0)), - ParseTokenAsFloat(GetRequiredToken(*ModelUVScaling,1)) - ); - } - - if(Cropping) { - crop[0] = ParseTokenAsInt(GetRequiredToken(*Cropping,0)); - crop[1] = ParseTokenAsInt(GetRequiredToken(*Cropping,1)); - crop[2] = ParseTokenAsInt(GetRequiredToken(*Cropping,2)); - crop[3] = ParseTokenAsInt(GetRequiredToken(*Cropping,3)); - } - else { - // vc8 doesn't support the crop() syntax in initialization lists - // (and vc9 WARNS about the new (i.e. compliant) behaviour). - crop[0] = crop[1] = crop[2] = crop[3] = 0; - } - - if(Texture_Alpha_Source) { - alphaSource = ParseTokenAsString(GetRequiredToken(*Texture_Alpha_Source,0)); - } - - props = GetPropertyTable(doc,"Texture.FbxFileTexture",element,sc); - - // 3DS Max and FBX SDK use "Scaling" and "Translation" instead of "ModelUVScaling" and "ModelUVTranslation". Use these properties if available. - bool ok; - const aiVector3D& scaling = PropertyGet<aiVector3D>(*props, "Scaling", ok); - if (ok) { - uvScaling.x = scaling.x; - uvScaling.y = scaling.y; - } - - const aiVector3D& trans = PropertyGet<aiVector3D>(*props, "Translation", ok); - if (ok) { - uvTrans.x = trans.x; - uvTrans.y = trans.y; - } - - // resolve video links - if(doc.Settings().readTextures) { - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID()); - for(const Connection* con : conns) { - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for texture link, ignoring",&element); - continue; - } - - const Video* const video = dynamic_cast<const Video*>(ob); - if(video) { - media = video; - } - } - } -} - - -Texture::~Texture() -{ - -} - -LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name) -: Object(id,element,name) -,blendMode(BlendMode_Modulate) -,alpha(1) -{ - const Scope& sc = GetRequiredScope(element); - - const Element* const BlendModes = sc["BlendModes"]; - const Element* const Alphas = sc["Alphas"]; - - - if(BlendModes!=0) - { - blendMode = (BlendMode)ParseTokenAsInt(GetRequiredToken(*BlendModes,0)); - } - if(Alphas!=0) - { - alpha = ParseTokenAsFloat(GetRequiredToken(*Alphas,0)); - } -} - -LayeredTexture::~LayeredTexture() -{ - -} - -void LayeredTexture::fillTexture(const Document& doc) -{ - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID()); - for(size_t i = 0; i < conns.size();++i) - { - const Connection* con = conns.at(i); - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for texture link, ignoring",&element); - continue; - } - - const Texture* const tex = dynamic_cast<const Texture*>(ob); - - textures.push_back(tex); - } -} - - -// ------------------------------------------------------------------------------------------------ -Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: Object(id,element,name) -, contentLength(0) -, content(0) -{ - const Scope& sc = GetRequiredScope(element); - - const Element* const Type = sc["Type"]; - const Element* const FileName = sc.FindElementCaseInsensitive("FileName"); //some files retain the information as "Filename", others "FileName", who knows - const Element* const RelativeFilename = sc["RelativeFilename"]; - const Element* const Content = sc["Content"]; - - if(Type) { - type = ParseTokenAsString(GetRequiredToken(*Type,0)); - } - - if(FileName) { - fileName = ParseTokenAsString(GetRequiredToken(*FileName,0)); - } - - if(RelativeFilename) { - relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0)); - } - - if(Content && !Content->Tokens().empty()) { - //this field is omitted when the embedded texture is already loaded, let's ignore if it's not found - try { - const Token& token = GetRequiredToken(*Content, 0); - const char* data = token.begin(); - if (!token.IsBinary()) { - if (*data != '"') { - DOMError("embedded content is not surrounded by quotation marks", &element); - } - else { - size_t targetLength = 0; - auto numTokens = Content->Tokens().size(); - // First time compute size (it could be large like 64Gb and it is good to allocate it once) - for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx) - { - const Token& dataToken = GetRequiredToken(*Content, tokenIdx); - size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes - const char* base64data = dataToken.begin() + 1; - const size_t outLength = Util::ComputeDecodedSizeBase64(base64data, tokenLength); - if (outLength == 0) - { - DOMError("Corrupted embedded content found", &element); - } - targetLength += outLength; - } - if (targetLength == 0) - { - DOMError("Corrupted embedded content found", &element); - } - content = new uint8_t[targetLength]; - contentLength = static_cast<uint64_t>(targetLength); - size_t dst_offset = 0; - for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx) - { - const Token& dataToken = GetRequiredToken(*Content, tokenIdx); - size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes - const char* base64data = dataToken.begin() + 1; - dst_offset += Util::DecodeBase64(base64data, tokenLength, content + dst_offset, targetLength - dst_offset); - } - if (targetLength != dst_offset) - { - delete[] content; - contentLength = 0; - DOMError("Corrupted embedded content found", &element); - } - } - } - else if (static_cast<size_t>(token.end() - data) < 5) { - DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element); - } - else if (*data != 'R') { - DOMWarning("video content is not raw binary data, ignoring", &element); - } - else { - // read number of elements - uint32_t len = 0; - ::memcpy(&len, data + 1, sizeof(len)); - AI_SWAP4(len); - - contentLength = len; - - content = new uint8_t[len]; - ::memcpy(content, data + 5, len); - } - } catch (const runtime_error& runtimeError) - { - //we don't need the content data for contents that has already been loaded - ASSIMP_LOG_DEBUG_F("Caught exception in FBXMaterial (likely because content was already loaded): ", - runtimeError.what()); - } - } - - props = GetPropertyTable(doc,"Video.FbxVideo",element,sc); -} - - -Video::~Video() -{ - if(content) { - delete[] content; - } -} - -} //!FBX -} //!Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp deleted file mode 100644 index 1386e2383c..0000000000 --- a/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXMeshGeometry.cpp - * @brief Assimp::FBX::MeshGeometry implementation - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include <functional> - -#include "FBXMeshGeometry.h" -#include "FBXDocument.h" -#include "FBXImporter.h" -#include "FBXImportSettings.h" -#include "FBXDocumentUtil.h" - - -namespace Assimp { -namespace FBX { - -using namespace Util; - -// ------------------------------------------------------------------------------------------------ -Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) - : Object(id, element, name) - , skin() -{ - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); - for(const Connection* con : conns) { - const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element); - if(sk) { - skin = sk; - } - const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element); - if (bsp) { - blendShapes.push_back(bsp); - } - } -} - -// ------------------------------------------------------------------------------------------------ -Geometry::~Geometry() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const { - return blendShapes; -} - -// ------------------------------------------------------------------------------------------------ -const Skin* Geometry::DeformerSkin() const { - return skin; -} - -// ------------------------------------------------------------------------------------------------ -MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Geometry(id, element,name, doc) -{ - const Scope* sc = element.Compound(); - if (!sc) { - DOMError("failed to read Geometry object (class: Mesh), no data scope found"); - } - - // must have Mesh elements: - const Element& Vertices = GetRequiredElement(*sc,"Vertices",&element); - const Element& PolygonVertexIndex = GetRequiredElement(*sc,"PolygonVertexIndex",&element); - - // optional Mesh elements: - const ElementCollection& Layer = sc->GetCollection("Layer"); - - std::vector<aiVector3D> tempVerts; - ParseVectorDataArray(tempVerts,Vertices); - - if(tempVerts.empty()) { - FBXImporter::LogWarn("encountered mesh with no vertices"); - } - - std::vector<int> tempFaces; - ParseVectorDataArray(tempFaces,PolygonVertexIndex); - - if(tempFaces.empty()) { - FBXImporter::LogWarn("encountered mesh with no faces"); - } - - m_vertices.reserve(tempFaces.size()); - m_faces.reserve(tempFaces.size() / 3); - - m_mapping_offsets.resize(tempVerts.size()); - m_mapping_counts.resize(tempVerts.size(),0); - m_mappings.resize(tempFaces.size()); - - const size_t vertex_count = tempVerts.size(); - - // generate output vertices, computing an adjacency table to - // preserve the mapping from fbx indices to *this* indexing. - unsigned int count = 0; - for(int index : tempFaces) { - const int absi = index < 0 ? (-index - 1) : index; - if(static_cast<size_t>(absi) >= vertex_count) { - DOMError("polygon vertex index out of range",&PolygonVertexIndex); - } - - m_vertices.push_back(tempVerts[absi]); - ++count; - - ++m_mapping_counts[absi]; - - if (index < 0) { - m_faces.push_back(count); - count = 0; - } - } - - unsigned int cursor = 0; - for (size_t i = 0, e = tempVerts.size(); i < e; ++i) { - m_mapping_offsets[i] = cursor; - cursor += m_mapping_counts[i]; - - m_mapping_counts[i] = 0; - } - - cursor = 0; - for(int index : tempFaces) { - const int absi = index < 0 ? (-index - 1) : index; - m_mappings[m_mapping_offsets[absi] + m_mapping_counts[absi]++] = cursor++; - } - - // if settings.readAllLayers is true: - // * read all layers, try to load as many vertex channels as possible - // if settings.readAllLayers is false: - // * read only the layer with index 0, but warn about any further layers - for (ElementMap::const_iterator it = Layer.first; it != Layer.second; ++it) { - const TokenList& tokens = (*it).second->Tokens(); - - const char* err; - const int index = ParseTokenAsInt(*tokens[0], err); - if(err) { - DOMError(err,&element); - } - - if(doc.Settings().readAllLayers || index == 0) { - const Scope& layer = GetRequiredScope(*(*it).second); - ReadLayer(layer); - } - else { - FBXImporter::LogWarn("ignoring additional geometry layers"); - } - } -} - -// ------------------------------------------------------------------------------------------------ -MeshGeometry::~MeshGeometry() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& MeshGeometry::GetVertices() const { - return m_vertices; -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& MeshGeometry::GetNormals() const { - return m_normals; -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& MeshGeometry::GetTangents() const { - return m_tangents; -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& MeshGeometry::GetBinormals() const { - return m_binormals; -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<unsigned int>& MeshGeometry::GetFaceIndexCounts() const { - return m_faces; -} - -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector2D>& MeshGeometry::GetTextureCoords( unsigned int index ) const { - static const std::vector<aiVector2D> empty; - return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : m_uvs[ index ]; -} - -std::string MeshGeometry::GetTextureCoordChannelName( unsigned int index ) const { - return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : m_uvNames[ index ]; -} - -const std::vector<aiColor4D>& MeshGeometry::GetVertexColors( unsigned int index ) const { - static const std::vector<aiColor4D> empty; - return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : m_colors[ index ]; -} - -const MatIndexArray& MeshGeometry::GetMaterialIndices() const { - return m_materials; -} -// ------------------------------------------------------------------------------------------------ -const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const { - if ( in_index >= m_mapping_counts.size() ) { - return NULL; - } - - ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() ); - count = m_mapping_counts[ in_index ]; - - ai_assert( m_mapping_offsets[ in_index ] + count <= m_mappings.size() ); - - return &m_mappings[ m_mapping_offsets[ in_index ] ]; -} - -// ------------------------------------------------------------------------------------------------ -unsigned int MeshGeometry::FaceForVertexIndex( unsigned int in_index ) const { - ai_assert( in_index < m_vertices.size() ); - - // in the current conversion pattern this will only be needed if - // weights are present, so no need to always pre-compute this table - if ( m_facesVertexStartIndices.empty() ) { - m_facesVertexStartIndices.resize( m_faces.size() + 1, 0 ); - - std::partial_sum( m_faces.begin(), m_faces.end(), m_facesVertexStartIndices.begin() + 1 ); - m_facesVertexStartIndices.pop_back(); - } - - ai_assert( m_facesVertexStartIndices.size() == m_faces.size() ); - const std::vector<unsigned int>::iterator it = std::upper_bound( - m_facesVertexStartIndices.begin(), - m_facesVertexStartIndices.end(), - in_index - ); - - return static_cast< unsigned int >( std::distance( m_facesVertexStartIndices.begin(), it - 1 ) ); -} - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadLayer(const Scope& layer) -{ - const ElementCollection& LayerElement = layer.GetCollection("LayerElement"); - for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) { - const Scope& elayer = GetRequiredScope(*(*eit).second); - - ReadLayerElement(elayer); - } -} - - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadLayerElement(const Scope& layerElement) -{ - const Element& Type = GetRequiredElement(layerElement,"Type"); - const Element& TypedIndex = GetRequiredElement(layerElement,"TypedIndex"); - - const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0)); - const int typedIndex = ParseTokenAsInt(GetRequiredToken(TypedIndex,0)); - - const Scope& top = GetRequiredScope(element); - const ElementCollection candidates = top.GetCollection(type); - - for (ElementMap::const_iterator it = candidates.first; it != candidates.second; ++it) { - const int index = ParseTokenAsInt(GetRequiredToken(*(*it).second,0)); - if(index == typedIndex) { - ReadVertexData(type,typedIndex,GetRequiredScope(*(*it).second)); - return; - } - } - - FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ") - << type << ", index: " << typedIndex); -} - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source) -{ - const std::string& MappingInformationType = ParseTokenAsString(GetRequiredToken( - GetRequiredElement(source,"MappingInformationType"),0) - ); - - const std::string& ReferenceInformationType = ParseTokenAsString(GetRequiredToken( - GetRequiredElement(source,"ReferenceInformationType"),0) - ); - - if (type == "LayerElementUV") { - if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { - FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" ); - return; - } - - const Element* Name = source["Name"]; - m_uvNames[index] = ""; - if(Name) { - m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0)); - } - - ReadVertexDataUV(m_uvs[index],source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementMaterial") { - if (m_materials.size() > 0) { - FBXImporter::LogError("ignoring additional material layer"); - return; - } - - std::vector<int> temp_materials; - - ReadVertexDataMaterials(temp_materials,source, - MappingInformationType, - ReferenceInformationType - ); - - // sometimes, there will be only negative entries. Drop the material - // layer in such a case (I guess it means a default material should - // be used). This is what the converter would do anyway, and it - // avoids losing the material if there are more material layers - // coming of which at least one contains actual data (did observe - // that with one test file). - const size_t count_neg = std::count_if(temp_materials.begin(),temp_materials.end(),[](int n) { return n < 0; }); - if(count_neg == temp_materials.size()) { - FBXImporter::LogWarn("ignoring dummy material layer (all entries -1)"); - return; - } - - std::swap(temp_materials, m_materials); - } - else if (type == "LayerElementNormal") { - if (m_normals.size() > 0) { - FBXImporter::LogError("ignoring additional normal layer"); - return; - } - - ReadVertexDataNormals(m_normals,source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementTangent") { - if (m_tangents.size() > 0) { - FBXImporter::LogError("ignoring additional tangent layer"); - return; - } - - ReadVertexDataTangents(m_tangents,source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementBinormal") { - if (m_binormals.size() > 0) { - FBXImporter::LogError("ignoring additional binormal layer"); - return; - } - - ReadVertexDataBinormals(m_binormals,source, - MappingInformationType, - ReferenceInformationType - ); - } - else if (type == "LayerElementColor") { - if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) { - FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" ); - return; - } - - ReadVertexDataColors(m_colors[index],source, - MappingInformationType, - ReferenceInformationType - ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Lengthy utility function to read and resolve a FBX vertex data array - that is, the -// output is in polygon vertex order. This logic is used for reading normals, UVs, colors, -// tangents .. -template <typename T> -void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType, - const char* dataElementName, - const char* indexDataElementName, - size_t vertex_count, - const std::vector<unsigned int>& mapping_counts, - const std::vector<unsigned int>& mapping_offsets, - const std::vector<unsigned int>& mappings) -{ - bool isDirect = ReferenceInformationType == "Direct"; - bool isIndexToDirect = ReferenceInformationType == "IndexToDirect"; - - // fall-back to direct data if there is no index data element - if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) { - isDirect = true; - isIndexToDirect = false; - } - - // handle permutations of Mapping and Reference type - it would be nice to - // deal with this more elegantly and with less redundancy, but right - // now it seems unavoidable. - if (MappingInformationType == "ByVertice" && isDirect) { - if (!HasElement(source, dataElementName)) { - return; - } - std::vector<T> tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); - - data_out.resize(vertex_count); - for (size_t i = 0, e = tempData.size(); i < e; ++i) { - - const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i]; - for (unsigned int j = istart; j < iend; ++j) { - data_out[mappings[j]] = tempData[i]; - } - } - } - else if (MappingInformationType == "ByVertice" && isIndexToDirect) { - std::vector<T> tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); - - data_out.resize(vertex_count); - - std::vector<int> uvIndices; - ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); - for (size_t i = 0, e = uvIndices.size(); i < e; ++i) { - - const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i]; - for (unsigned int j = istart; j < iend; ++j) { - if (static_cast<size_t>(uvIndices[i]) >= tempData.size()) { - DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); - } - data_out[mappings[j]] = tempData[uvIndices[i]]; - } - } - } - else if (MappingInformationType == "ByPolygonVertex" && isDirect) { - std::vector<T> tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); - - if (tempData.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << tempData.size() << ", expected " << vertex_count - ); - return; - } - - data_out.swap(tempData); - } - else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) { - std::vector<T> tempData; - ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); - - data_out.resize(vertex_count); - - std::vector<int> uvIndices; - ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); - - if (uvIndices.size() != vertex_count) { - FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping"); - return; - } - - const T empty; - unsigned int next = 0; - for(int i : uvIndices) { - if ( -1 == i ) { - data_out[ next++ ] = empty; - continue; - } - if (static_cast<size_t>(i) >= tempData.size()) { - DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); - } - - data_out[next++] = tempData[i]; - } - } - else { - FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); - } -} - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - ResolveVertexDataArray(normals_out,source,MappingInformationType,ReferenceInformationType, - "Normals", - "NormalsIndex", - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); -} - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - ResolveVertexDataArray(uv_out,source,MappingInformationType,ReferenceInformationType, - "UV", - "UVIndex", - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); -} - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - ResolveVertexDataArray(colors_out,source,MappingInformationType,ReferenceInformationType, - "Colors", - "ColorIndex", - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); -} - -// ------------------------------------------------------------------------------------------------ -static const char *TangentIndexToken = "TangentIndex"; -static const char *TangentsIndexToken = "TangentsIndex"; - -void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent"; - const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken : TangentIndexToken; - ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType, - str, - strIdx, - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); -} - -// ------------------------------------------------------------------------------------------------ -static const std::string BinormalIndexToken = "BinormalIndex"; -static const std::string BinormalsIndexToken = "BinormalsIndex"; - -void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal"; - const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str(); - ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, - str, - strIdx, - m_vertices.size(), - m_mapping_counts, - m_mapping_offsets, - m_mappings); -} - - -// ------------------------------------------------------------------------------------------------ -void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType) -{ - const size_t face_count = m_faces.size(); - if( 0 == face_count ) - { - return; - } - - // materials are handled separately. First of all, they are assigned per-face - // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect - // has a slightly different meaning for materials. - ParseVectorDataArray(materials_out,GetRequiredElement(source,"Materials")); - - if (MappingInformationType == "AllSame") { - // easy - same material for all faces - if (materials_out.empty()) { - FBXImporter::LogError(Formatter::format("expected material index, ignoring")); - return; - } else if (materials_out.size() > 1) { - FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one")); - materials_out.clear(); - } - - materials_out.resize(m_vertices.size()); - std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0)); - } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") { - materials_out.resize(face_count); - - if(materials_out.size() != face_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << materials_out.size() << ", expected " << face_count - ); - return; - } - } else { - FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); - } -} -// ------------------------------------------------------------------------------------------------ -ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Geometry(id, element, name, doc) { - const Scope *sc = element.Compound(); - if (nullptr == sc) { - DOMError("failed to read Geometry object (class: Shape), no data scope found"); - } - const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element); - const Element& Normals = GetRequiredElement(*sc, "Normals", &element); - const Element& Vertices = GetRequiredElement(*sc, "Vertices", &element); - ParseVectorDataArray(m_indices, Indexes); - ParseVectorDataArray(m_vertices, Vertices); - ParseVectorDataArray(m_normals, Normals); -} - -// ------------------------------------------------------------------------------------------------ -ShapeGeometry::~ShapeGeometry() { - // empty -} -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& ShapeGeometry::GetVertices() const { - return m_vertices; -} -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& ShapeGeometry::GetNormals() const { - return m_normals; -} -// ------------------------------------------------------------------------------------------------ -const std::vector<unsigned int>& ShapeGeometry::GetIndices() const { - return m_indices; -} -// ------------------------------------------------------------------------------------------------ -LineGeometry::LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) - : Geometry(id, element, name, doc) -{ - const Scope* sc = element.Compound(); - if (!sc) { - DOMError("failed to read Geometry object (class: Line), no data scope found"); - } - const Element& Points = GetRequiredElement(*sc, "Points", &element); - const Element& PointsIndex = GetRequiredElement(*sc, "PointsIndex", &element); - ParseVectorDataArray(m_vertices, Points); - ParseVectorDataArray(m_indices, PointsIndex); -} - -// ------------------------------------------------------------------------------------------------ -LineGeometry::~LineGeometry() { - // empty -} -// ------------------------------------------------------------------------------------------------ -const std::vector<aiVector3D>& LineGeometry::GetVertices() const { - return m_vertices; -} -// ------------------------------------------------------------------------------------------------ -const std::vector<int>& LineGeometry::GetIndices() const { - return m_indices; -} -} // !FBX -} // !Assimp -#endif - diff --git a/thirdparty/assimp/code/FBX/FBXMeshGeometry.h b/thirdparty/assimp/code/FBX/FBXMeshGeometry.h deleted file mode 100644 index d6d4512177..0000000000 --- a/thirdparty/assimp/code/FBX/FBXMeshGeometry.h +++ /dev/null @@ -1,235 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXImporter.h -* @brief Declaration of the FBX main importer class -*/ -#ifndef INCLUDED_AI_FBX_MESHGEOMETRY_H -#define INCLUDED_AI_FBX_MESHGEOMETRY_H - -#include "FBXParser.h" -#include "FBXDocument.h" - -namespace Assimp { -namespace FBX { - -/** - * DOM base class for all kinds of FBX geometry - */ -class Geometry : public Object -{ -public: - Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc ); - virtual ~Geometry(); - - /** Get the Skin attached to this geometry or NULL */ - const Skin* DeformerSkin() const; - - /** Get the BlendShape attached to this geometry or NULL */ - const std::vector<const BlendShape*>& GetBlendShapes() const; - -private: - const Skin* skin; - std::vector<const BlendShape*> blendShapes; - -}; - -typedef std::vector<int> MatIndexArray; - - -/** - * DOM class for FBX geometry of type "Mesh" - */ -class MeshGeometry : public Geometry -{ -public: - /** The class constructor */ - MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc ); - - /** The class destructor */ - virtual ~MeshGeometry(); - - /** Get a list of all vertex points, non-unique*/ - const std::vector<aiVector3D>& GetVertices() const; - - /** Get a list of all vertex normals or an empty array if - * no normals are specified. */ - const std::vector<aiVector3D>& GetNormals() const; - - /** Get a list of all vertex tangents or an empty array - * if no tangents are specified */ - const std::vector<aiVector3D>& GetTangents() const; - - /** Get a list of all vertex bi-normals or an empty array - * if no bi-normals are specified */ - const std::vector<aiVector3D>& GetBinormals() const; - - /** Return list of faces - each entry denotes a face and specifies - * how many vertices it has. Vertices are taken from the - * vertex data arrays in sequential order. */ - const std::vector<unsigned int>& GetFaceIndexCounts() const; - - /** Get a UV coordinate slot, returns an empty array if - * the requested slot does not exist. */ - const std::vector<aiVector2D>& GetTextureCoords( unsigned int index ) const; - - /** Get a UV coordinate slot, returns an empty array if - * the requested slot does not exist. */ - std::string GetTextureCoordChannelName( unsigned int index ) const; - - /** Get a vertex color coordinate slot, returns an empty array if - * the requested slot does not exist. */ - const std::vector<aiColor4D>& GetVertexColors( unsigned int index ) const; - - /** Get per-face-vertex material assignments */ - const MatIndexArray& GetMaterialIndices() const; - - /** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL - * if the vertex index is not valid. */ - const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const; - - /** Determine the face to which a particular output vertex index belongs. - * This mapping is always unique. */ - unsigned int FaceForVertexIndex( unsigned int in_index ) const; -private: - void ReadLayer( const Scope& layer ); - void ReadLayerElement( const Scope& layerElement ); - void ReadVertexData( const std::string& type, int index, const Scope& source ); - - void ReadVertexDataUV( std::vector<aiVector2D>& uv_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType ); - - void ReadVertexDataNormals( std::vector<aiVector3D>& normals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType ); - - void ReadVertexDataColors( std::vector<aiColor4D>& colors_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType ); - - void ReadVertexDataTangents( std::vector<aiVector3D>& tangents_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType ); - - void ReadVertexDataBinormals( std::vector<aiVector3D>& binormals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType ); - - void ReadVertexDataMaterials( MatIndexArray& materials_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType ); - -private: - // cached data arrays - MatIndexArray m_materials; - std::vector<aiVector3D> m_vertices; - std::vector<unsigned int> m_faces; - mutable std::vector<unsigned int> m_facesVertexStartIndices; - std::vector<aiVector3D> m_tangents; - std::vector<aiVector3D> m_binormals; - std::vector<aiVector3D> m_normals; - - std::string m_uvNames[ AI_MAX_NUMBER_OF_TEXTURECOORDS ]; - std::vector<aiVector2D> m_uvs[ AI_MAX_NUMBER_OF_TEXTURECOORDS ]; - std::vector<aiColor4D> m_colors[ AI_MAX_NUMBER_OF_COLOR_SETS ]; - - std::vector<unsigned int> m_mapping_counts; - std::vector<unsigned int> m_mapping_offsets; - std::vector<unsigned int> m_mappings; -}; - -/** -* DOM class for FBX geometry of type "Shape" -*/ -class ShapeGeometry : public Geometry -{ -public: - /** The class constructor */ - ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc); - - /** The class destructor */ - virtual ~ShapeGeometry(); - - /** Get a list of all vertex points, non-unique*/ - const std::vector<aiVector3D>& GetVertices() const; - - /** Get a list of all vertex normals or an empty array if - * no normals are specified. */ - const std::vector<aiVector3D>& GetNormals() const; - - /** Return list of vertex indices. */ - const std::vector<unsigned int>& GetIndices() const; - -private: - std::vector<aiVector3D> m_vertices; - std::vector<aiVector3D> m_normals; - std::vector<unsigned int> m_indices; -}; -/** -* DOM class for FBX geometry of type "Line" -*/ -class LineGeometry : public Geometry -{ -public: - /** The class constructor */ - LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc); - - /** The class destructor */ - virtual ~LineGeometry(); - - /** Get a list of all vertex points, non-unique*/ - const std::vector<aiVector3D>& GetVertices() const; - - /** Return list of vertex indices. */ - const std::vector<int>& GetIndices() const; - -private: - std::vector<aiVector3D> m_vertices; - std::vector<int> m_indices; -}; - -} -} - -#endif // INCLUDED_AI_FBX_MESHGEOMETRY_H - diff --git a/thirdparty/assimp/code/FBX/FBXModel.cpp b/thirdparty/assimp/code/FBX/FBXModel.cpp deleted file mode 100644 index 589af36ac7..0000000000 --- a/thirdparty/assimp/code/FBX/FBXModel.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXModel.cpp - * @brief Assimp::FBX::Model implementation - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXParser.h" -#include "FBXMeshGeometry.h" -#include "FBXDocument.h" -#include "FBXImporter.h" -#include "FBXDocumentUtil.h" - -namespace Assimp { -namespace FBX { - -using namespace Util; - -// ------------------------------------------------------------------------------------------------ -Model::Model(uint64_t id, const Element& element, const Document& doc, const std::string& name) - : Object(id,element,name) - , shading("Y") -{ - const Scope& sc = GetRequiredScope(element); - const Element* const Shading = sc["Shading"]; - const Element* const Culling = sc["Culling"]; - - if(Shading) { - shading = GetRequiredToken(*Shading,0).StringContents(); - } - - if (Culling) { - culling = ParseTokenAsString(GetRequiredToken(*Culling,0)); - } - - props = GetPropertyTable(doc,"Model.FbxNode",element,sc); - ResolveLinks(element,doc); -} - -// ------------------------------------------------------------------------------------------------ -Model::~Model() -{ - -} - -// ------------------------------------------------------------------------------------------------ -void Model::ResolveLinks(const Element& element, const Document& doc) -{ - const char* const arr[] = {"Geometry","Material","NodeAttribute"}; - - // resolve material - const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),arr, 3); - - materials.reserve(conns.size()); - geometry.reserve(conns.size()); - attributes.reserve(conns.size()); - for(const Connection* con : conns) { - - // material and geometry links should be Object-Object connections - if (con->PropertyName().length()) { - continue; - } - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for incoming Model link, ignoring",&element); - continue; - } - - const Material* const mat = dynamic_cast<const Material*>(ob); - if(mat) { - materials.push_back(mat); - continue; - } - - const Geometry* const geo = dynamic_cast<const Geometry*>(ob); - if(geo) { - geometry.push_back(geo); - continue; - } - - const NodeAttribute* const att = dynamic_cast<const NodeAttribute*>(ob); - if(att) { - attributes.push_back(att); - continue; - } - - DOMWarning("source object for model link is neither Material, NodeAttribute nor Geometry, ignoring",&element); - continue; - } -} - -// ------------------------------------------------------------------------------------------------ -bool Model::IsNull() const -{ - const std::vector<const NodeAttribute*>& attrs = GetAttributes(); - for(const NodeAttribute* att : attrs) { - - const Null* null_tag = dynamic_cast<const Null*>(att); - if(null_tag) { - return true; - } - } - - return false; -} - - -} //!FBX -} //!Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp b/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp deleted file mode 100644 index b72e5637ee..0000000000 --- a/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXNoteAttribute.cpp - * @brief Assimp::FBX::NodeAttribute (and subclasses) implementation - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXParser.h" -#include "FBXDocument.h" -#include "FBXImporter.h" -#include "FBXDocumentUtil.h" - -namespace Assimp { -namespace FBX { - -using namespace Util; - -// ------------------------------------------------------------------------------------------------ -NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: Object(id,element,name) -, props() -{ - const Scope& sc = GetRequiredScope(element); - - const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2)); - - // hack on the deriving type but Null/LimbNode attributes are the only case in which - // the property table is by design absent and no warning should be generated - // for it. - const bool is_null_or_limb = !strcmp(classname.c_str(), "Null") || !strcmp(classname.c_str(), "LimbNode"); - props = GetPropertyTable(doc,"NodeAttribute.Fbx" + classname,element,sc, is_null_or_limb); -} - - -// ------------------------------------------------------------------------------------------------ -NodeAttribute::~NodeAttribute() -{ - // empty -} - - -// ------------------------------------------------------------------------------------------------ -CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name) - : NodeAttribute(id,element,doc,name) -{ - const Scope& sc = GetRequiredScope(element); - const Element* const CameraId = sc["CameraId"]; - const Element* const CameraName = sc["CameraName"]; - const Element* const CameraIndexName = sc["CameraIndexName"]; - - if(CameraId) { - cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId,0)); - } - - if(CameraName) { - cameraName = GetRequiredToken(*CameraName,0).StringContents(); - } - - if(CameraIndexName && CameraIndexName->Tokens().size()) { - cameraIndexName = GetRequiredToken(*CameraIndexName,0).StringContents(); - } -} - -// ------------------------------------------------------------------------------------------------ -CameraSwitcher::~CameraSwitcher() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: NodeAttribute(id,element,doc,name) -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -Camera::~Camera() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: NodeAttribute(id,element,doc,name) -{ - // empty -} - - -// ------------------------------------------------------------------------------------------------ -Light::~Light() -{ -} - - -// ------------------------------------------------------------------------------------------------ -Null::Null(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: NodeAttribute(id,element,doc,name) -{ - -} - - -// ------------------------------------------------------------------------------------------------ -Null::~Null() -{ - -} - - -// ------------------------------------------------------------------------------------------------ -LimbNode::LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name) -: NodeAttribute(id,element,doc,name) -{ - -} - - -// ------------------------------------------------------------------------------------------------ -LimbNode::~LimbNode() -{ - -} - -} -} - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXParser.cpp b/thirdparty/assimp/code/FBX/FBXParser.cpp deleted file mode 100644 index 4a9346040d..0000000000 --- a/thirdparty/assimp/code/FBX/FBXParser.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXParser.cpp - * @brief Implementation of the FBX parser and the rudimentary DOM that we use - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include <zlib.h> -#else -# include "../contrib/zlib/zlib.h" -#endif - -#include "FBXTokenizer.h" -#include "FBXParser.h" -#include "FBXUtil.h" - -#include <assimp/ParsingUtils.h> -#include <assimp/fast_atof.h> -#include <assimp/ByteSwapper.h> - -#include <iostream> - -using namespace Assimp; -using namespace Assimp::FBX; - -namespace { - - // ------------------------------------------------------------------------------------------------ - // signal parse error, this is always unrecoverable. Throws DeadlyImportError. - AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX; - AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) - { - throw DeadlyImportError(Util::AddTokenText("FBX-Parser",message,&token)); - } - - // ------------------------------------------------------------------------------------------------ - AI_WONT_RETURN void ParseError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX; - AI_WONT_RETURN void ParseError(const std::string& message, const Element* element) - { - if(element) { - ParseError(message,element->KeyToken()); - } - throw DeadlyImportError("FBX-Parser " + message); - } - - - // ------------------------------------------------------------------------------------------------ - void ParseError(const std::string& message, TokenPtr token) - { - if(token) { - ParseError(message, *token); - } - ParseError(message); - } - - // Initially, we did reinterpret_cast, breaking strict aliasing rules. - // This actually caused trouble on Android, so let's be safe this time. - // https://github.com/assimp/assimp/issues/24 - template <typename T> - T SafeParse(const char* data, const char* end) { - // Actual size validation happens during Tokenization so - // this is valid as an assertion. - (void)(end); - ai_assert(static_cast<size_t>(end - data) >= sizeof(T)); - T result = static_cast<T>(0); - ::memcpy(&result, data, sizeof(T)); - return result; - } -} - -namespace Assimp { -namespace FBX { - -// ------------------------------------------------------------------------------------------------ -Element::Element(const Token& key_token, Parser& parser) -: key_token(key_token) -{ - TokenPtr n = nullptr; - do { - n = parser.AdvanceToNextToken(); - if(!n) { - ParseError("unexpected end of file, expected closing bracket",parser.LastToken()); - } - - if (n->Type() == TokenType_DATA) { - tokens.push_back(n); - TokenPtr prev = n; - n = parser.AdvanceToNextToken(); - if(!n) { - ParseError("unexpected end of file, expected bracket, comma or key",parser.LastToken()); - } - - const TokenType ty = n->Type(); - - // some exporters are missing a comma on the next line - if (ty == TokenType_DATA && prev->Type() == TokenType_DATA && (n->Line() == prev->Line() + 1)) { - tokens.push_back(n); - continue; - } - - if (ty != TokenType_OPEN_BRACKET && ty != TokenType_CLOSE_BRACKET && ty != TokenType_COMMA && ty != TokenType_KEY) { - ParseError("unexpected token; expected bracket, comma or key",n); - } - } - - if (n->Type() == TokenType_OPEN_BRACKET) { - compound.reset(new Scope(parser)); - - // current token should be a TOK_CLOSE_BRACKET - n = parser.CurrentToken(); - ai_assert(n); - - if (n->Type() != TokenType_CLOSE_BRACKET) { - ParseError("expected closing bracket",n); - } - - parser.AdvanceToNextToken(); - return; - } - } - while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET); -} - -// ------------------------------------------------------------------------------------------------ -Element::~Element() -{ - // no need to delete tokens, they are owned by the parser -} - -// ------------------------------------------------------------------------------------------------ -Scope::Scope(Parser& parser,bool topLevel) -{ - if(!topLevel) { - TokenPtr t = parser.CurrentToken(); - if (t->Type() != TokenType_OPEN_BRACKET) { - ParseError("expected open bracket",t); - } - } - - TokenPtr n = parser.AdvanceToNextToken(); - if(n == NULL) { - ParseError("unexpected end of file"); - } - - // note: empty scopes are allowed - while(n->Type() != TokenType_CLOSE_BRACKET) { - if (n->Type() != TokenType_KEY) { - ParseError("unexpected token, expected TOK_KEY",n); - } - - const std::string& str = n->StringContents(); - elements.insert(ElementMap::value_type(str,new_Element(*n,parser))); - - // Element() should stop at the next Key token (or right after a Close token) - n = parser.CurrentToken(); - if(n == NULL) { - if (topLevel) { - return; - } - ParseError("unexpected end of file",parser.LastToken()); - } - } -} - -// ------------------------------------------------------------------------------------------------ -Scope::~Scope() -{ - for(ElementMap::value_type& v : elements) { - delete v.second; - } -} - -// ------------------------------------------------------------------------------------------------ -Parser::Parser (const TokenList& tokens, bool is_binary) -: tokens(tokens) -, last() -, current() -, cursor(tokens.begin()) -, is_binary(is_binary) -{ - root.reset(new Scope(*this,true)); -} - -// ------------------------------------------------------------------------------------------------ -Parser::~Parser() -{ - // empty -} - -// ------------------------------------------------------------------------------------------------ -TokenPtr Parser::AdvanceToNextToken() -{ - last = current; - if (cursor == tokens.end()) { - current = NULL; - } else { - current = *cursor++; - } - return current; -} - -// ------------------------------------------------------------------------------------------------ -TokenPtr Parser::CurrentToken() const -{ - return current; -} - -// ------------------------------------------------------------------------------------------------ -TokenPtr Parser::LastToken() const -{ - return last; -} - -// ------------------------------------------------------------------------------------------------ -uint64_t ParseTokenAsID(const Token& t, const char*& err_out) -{ - err_out = NULL; - - if (t.Type() != TokenType_DATA) { - err_out = "expected TOK_DATA token"; - return 0L; - } - - if(t.IsBinary()) - { - const char* data = t.begin(); - if (data[0] != 'L') { - err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)"; - return 0L; - } - - BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end()); - AI_SWAP8(id); - return id; - } - - // XXX: should use size_t here - unsigned int length = static_cast<unsigned int>(t.end() - t.begin()); - ai_assert(length > 0); - - const char* out = nullptr; - const uint64_t id = strtoul10_64(t.begin(),&out,&length); - if (out > t.end()) { - err_out = "failed to parse ID (text)"; - return 0L; - } - - return id; -} - -// ------------------------------------------------------------------------------------------------ -size_t ParseTokenAsDim(const Token& t, const char*& err_out) -{ - // same as ID parsing, except there is a trailing asterisk - err_out = NULL; - - if (t.Type() != TokenType_DATA) { - err_out = "expected TOK_DATA token"; - return 0; - } - - if(t.IsBinary()) - { - const char* data = t.begin(); - if (data[0] != 'L') { - err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)"; - return 0; - } - - BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end()); - AI_SWAP8(id); - return static_cast<size_t>(id); - } - - if(*t.begin() != '*') { - err_out = "expected asterisk before array dimension"; - return 0; - } - - // XXX: should use size_t here - unsigned int length = static_cast<unsigned int>(t.end() - t.begin()); - if(length == 0) { - err_out = "expected valid integer number after asterisk"; - return 0; - } - - const char* out = nullptr; - const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length)); - if (out > t.end()) { - err_out = "failed to parse ID"; - return 0; - } - - return id; -} - - -// ------------------------------------------------------------------------------------------------ -float ParseTokenAsFloat(const Token& t, const char*& err_out) -{ - err_out = NULL; - - if (t.Type() != TokenType_DATA) { - err_out = "expected TOK_DATA token"; - return 0.0f; - } - - if(t.IsBinary()) - { - const char* data = t.begin(); - if (data[0] != 'F' && data[0] != 'D') { - err_out = "failed to parse F(loat) or D(ouble), unexpected data type (binary)"; - return 0.0f; - } - - if (data[0] == 'F') { - return SafeParse<float>(data+1, t.end()); - } - else { - return static_cast<float>( SafeParse<double>(data+1, t.end()) ); - } - } - - // need to copy the input string to a temporary buffer - // first - next in the fbx token stream comes ',', - // which fast_atof could interpret as decimal point. -#define MAX_FLOAT_LENGTH 31 - char temp[MAX_FLOAT_LENGTH + 1]; - const size_t length = static_cast<size_t>(t.end()-t.begin()); - std::copy(t.begin(),t.end(),temp); - temp[std::min(static_cast<size_t>(MAX_FLOAT_LENGTH),length)] = '\0'; - - return fast_atof(temp); -} - - -// ------------------------------------------------------------------------------------------------ -int ParseTokenAsInt(const Token& t, const char*& err_out) -{ - err_out = NULL; - - if (t.Type() != TokenType_DATA) { - err_out = "expected TOK_DATA token"; - return 0; - } - - if(t.IsBinary()) - { - const char* data = t.begin(); - if (data[0] != 'I') { - err_out = "failed to parse I(nt), unexpected data type (binary)"; - return 0; - } - - BE_NCONST int32_t ival = SafeParse<int32_t>(data+1, t.end()); - AI_SWAP4(ival); - return static_cast<int>(ival); - } - - ai_assert(static_cast<size_t>(t.end() - t.begin()) > 0); - - const char* out; - const int intval = strtol10(t.begin(),&out); - if (out != t.end()) { - err_out = "failed to parse ID"; - return 0; - } - - return intval; -} - - -// ------------------------------------------------------------------------------------------------ -int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) -{ - err_out = NULL; - - if (t.Type() != TokenType_DATA) { - err_out = "expected TOK_DATA token"; - return 0L; - } - - if (t.IsBinary()) - { - const char* data = t.begin(); - if (data[0] != 'L') { - err_out = "failed to parse Int64, unexpected data type"; - return 0L; - } - - BE_NCONST int64_t id = SafeParse<int64_t>(data + 1, t.end()); - AI_SWAP8(id); - return id; - } - - // XXX: should use size_t here - unsigned int length = static_cast<unsigned int>(t.end() - t.begin()); - ai_assert(length > 0); - - const char* out = nullptr; - const int64_t id = strtol10_64(t.begin(), &out, &length); - if (out > t.end()) { - err_out = "failed to parse Int64 (text)"; - return 0L; - } - - return id; -} - -// ------------------------------------------------------------------------------------------------ -std::string ParseTokenAsString(const Token& t, const char*& err_out) -{ - err_out = NULL; - - if (t.Type() != TokenType_DATA) { - err_out = "expected TOK_DATA token"; - return ""; - } - - if(t.IsBinary()) - { - const char* data = t.begin(); - if (data[0] != 'S') { - err_out = "failed to parse S(tring), unexpected data type (binary)"; - return ""; - } - - // read string length - BE_NCONST int32_t len = SafeParse<int32_t>(data+1, t.end()); - AI_SWAP4(len); - - ai_assert(t.end() - data == 5 + len); - return std::string(data + 5, len); - } - - const size_t length = static_cast<size_t>(t.end() - t.begin()); - if(length < 2) { - err_out = "token is too short to hold a string"; - return ""; - } - - const char* s = t.begin(), *e = t.end() - 1; - if (*s != '\"' || *e != '\"') { - err_out = "expected double quoted string"; - return ""; - } - - return std::string(s+1,length-2); -} - - -namespace { - -// ------------------------------------------------------------------------------------------------ -// read the type code and element count of a binary data array and stop there -void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uint32_t& count, - const Element& el) -{ - if (static_cast<size_t>(end-data) < 5) { - ParseError("binary data array is too short, need five (5) bytes for type signature and element count",&el); - } - - // data type - type = *data; - - // read number of elements - BE_NCONST uint32_t len = SafeParse<uint32_t>(data+1, end); - AI_SWAP4(len); - - count = len; - data += 5; -} - - -// ------------------------------------------------------------------------------------------------ -// read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header) -void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end, - std::vector<char>& buff, - const Element& /*el*/) -{ - BE_NCONST uint32_t encmode = SafeParse<uint32_t>(data, end); - AI_SWAP4(encmode); - data += 4; - - // next comes the compressed length - BE_NCONST uint32_t comp_len = SafeParse<uint32_t>(data, end); - AI_SWAP4(comp_len); - data += 4; - - ai_assert(data + comp_len == end); - - // determine the length of the uncompressed data by looking at the type signature - uint32_t stride = 0; - switch(type) - { - case 'f': - case 'i': - stride = 4; - break; - - case 'd': - case 'l': - stride = 8; - break; - - default: - ai_assert(false); - }; - - const uint32_t full_length = stride * count; - buff.resize(full_length); - - if(encmode == 0) { - ai_assert(full_length == comp_len); - - // plain data, no compression - std::copy(data, end, buff.begin()); - } - else if(encmode == 1) { - // zlib/deflate, next comes ZIP head (0x78 0x01) - // see http://www.ietf.org/rfc/rfc1950.txt - - z_stream zstream; - zstream.opaque = Z_NULL; - zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; - zstream.data_type = Z_BINARY; - - // http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib - if(Z_OK != inflateInit(&zstream)) { - ParseError("failure initializing zlib"); - } - - zstream.next_in = reinterpret_cast<Bytef*>( const_cast<char*>(data) ); - zstream.avail_in = comp_len; - - zstream.avail_out = static_cast<uInt>(buff.size()); - zstream.next_out = reinterpret_cast<Bytef*>(&*buff.begin()); - const int ret = inflate(&zstream, Z_FINISH); - - if (ret != Z_STREAM_END && ret != Z_OK) { - ParseError("failure decompressing compressed data section"); - } - - // terminate zlib - inflateEnd(&zstream); - } -#ifdef ASSIMP_BUILD_DEBUG - else { - // runtime check for this happens at tokenization stage - ai_assert(false); - } -#endif - - data += comp_len; - ai_assert(data == end); -} - -} // !anon - - -// ------------------------------------------------------------------------------------------------ -// read an array of float3 tuples -void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el) -{ - out.resize( 0 ); - - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(count % 3 != 0) { - ParseError("number of floats is not a multiple of three (3) (binary)",&el); - } - - if(!count) { - return; - } - - if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); - - const uint32_t count3 = count / 3; - out.reserve(count3); - - if (type == 'd') { - const double* d = reinterpret_cast<const double*>(&buff[0]); - for (unsigned int i = 0; i < count3; ++i, d += 3) { - out.push_back(aiVector3D(static_cast<ai_real>(d[0]), - static_cast<ai_real>(d[1]), - static_cast<ai_real>(d[2]))); - } - // for debugging - /*for ( size_t i = 0; i < out.size(); i++ ) { - aiVector3D vec3( out[ i ] ); - std::stringstream stream; - stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl; - DefaultLogger::get()->info( stream.str() ); - }*/ - } - else if (type == 'f') { - const float* f = reinterpret_cast<const float*>(&buff[0]); - for (unsigned int i = 0; i < count3; ++i, f += 3) { - out.push_back(aiVector3D(f[0],f[1],f[2])); - } - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // may throw bad_alloc if the input is rubbish, but this need - // not to be prevented - importing would fail but we wouldn't - // crash since assimp handles this case properly. - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - if (a.Tokens().size() % 3 != 0) { - ParseError("number of floats is not a multiple of three (3)",&el); - } - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - aiVector3D v; - v.x = ParseTokenAsFloat(**it++); - v.y = ParseTokenAsFloat(**it++); - v.z = ParseTokenAsFloat(**it++); - - out.push_back(v); - } -} - - -// ------------------------------------------------------------------------------------------------ -// read an array of color4 tuples -void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(count % 4 != 0) { - ParseError("number of floats is not a multiple of four (4) (binary)",&el); - } - - if(!count) { - return; - } - - if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); - - const uint32_t count4 = count / 4; - out.reserve(count4); - - if (type == 'd') { - const double* d = reinterpret_cast<const double*>(&buff[0]); - for (unsigned int i = 0; i < count4; ++i, d += 4) { - out.push_back(aiColor4D(static_cast<float>(d[0]), - static_cast<float>(d[1]), - static_cast<float>(d[2]), - static_cast<float>(d[3]))); - } - } - else if (type == 'f') { - const float* f = reinterpret_cast<const float*>(&buff[0]); - for (unsigned int i = 0; i < count4; ++i, f += 4) { - out.push_back(aiColor4D(f[0],f[1],f[2],f[3])); - } - } - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() above - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - if (a.Tokens().size() % 4 != 0) { - ParseError("number of floats is not a multiple of four (4)",&el); - } - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - aiColor4D v; - v.r = ParseTokenAsFloat(**it++); - v.g = ParseTokenAsFloat(**it++); - v.b = ParseTokenAsFloat(**it++); - v.a = ParseTokenAsFloat(**it++); - - out.push_back(v); - } -} - - -// ------------------------------------------------------------------------------------------------ -// read an array of float2 tuples -void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(count % 2 != 0) { - ParseError("number of floats is not a multiple of two (2) (binary)",&el); - } - - if(!count) { - return; - } - - if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); - - const uint32_t count2 = count / 2; - out.reserve(count2); - - if (type == 'd') { - const double* d = reinterpret_cast<const double*>(&buff[0]); - for (unsigned int i = 0; i < count2; ++i, d += 2) { - out.push_back(aiVector2D(static_cast<float>(d[0]), - static_cast<float>(d[1]))); - } - } - else if (type == 'f') { - const float* f = reinterpret_cast<const float*>(&buff[0]); - for (unsigned int i = 0; i < count2; ++i, f += 2) { - out.push_back(aiVector2D(f[0],f[1])); - } - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() above - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - if (a.Tokens().size() % 2 != 0) { - ParseError("number of floats is not a multiple of two (2)",&el); - } - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - aiVector2D v; - v.x = ParseTokenAsFloat(**it++); - v.y = ParseTokenAsFloat(**it++); - - out.push_back(v); - } -} - - -// ------------------------------------------------------------------------------------------------ -// read an array of ints -void ParseVectorDataArray(std::vector<int>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(!count) { - return; - } - - if (type != 'i') { - ParseError("expected int array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * 4); - - out.reserve(count); - - const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++ip) { - BE_NCONST int32_t val = *ip; - AI_SWAP4(val); - out.push_back(val); - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - const int ival = ParseTokenAsInt(**it++); - out.push_back(ival); - } -} - - -// ------------------------------------------------------------------------------------------------ -// read an array of floats -void ParseVectorDataArray(std::vector<float>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(!count) { - return; - } - - if (type != 'd' && type != 'f') { - ParseError("expected float or double array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); - - if (type == 'd') { - const double* d = reinterpret_cast<const double*>(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++d) { - out.push_back(static_cast<float>(*d)); - } - } - else if (type == 'f') { - const float* f = reinterpret_cast<const float*>(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++f) { - out.push_back(*f); - } - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - const float ival = ParseTokenAsFloat(**it++); - out.push_back(ival); - } -} - -// ------------------------------------------------------------------------------------------------ -// read an array of uints -void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(!count) { - return; - } - - if (type != 'i') { - ParseError("expected (u)int array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * 4); - - out.reserve(count); - - const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++ip) { - BE_NCONST int32_t val = *ip; - if(val < 0) { - ParseError("encountered negative integer index (binary)"); - } - - AI_SWAP4(val); - out.push_back(val); - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - const int ival = ParseTokenAsInt(**it++); - if(ival < 0) { - ParseError("encountered negative integer index"); - } - out.push_back(static_cast<unsigned int>(ival)); - } -} - - -// ------------------------------------------------------------------------------------------------ -// read an array of uint64_ts -void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if(tok.empty()) { - ParseError("unexpected empty element",&el); - } - - if(tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if(!count) { - return; - } - - if (type != 'l') { - ParseError("expected long array (binary)",&el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * 8); - - out.reserve(count); - - const uint64_t* ip = reinterpret_cast<const uint64_t*>(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++ip) { - BE_NCONST uint64_t val = *ip; - AI_SWAP8(val); - out.push_back(val); - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope,"a",&el); - - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { - const uint64_t ival = ParseTokenAsID(**it++); - - out.push_back(ival); - } -} - -// ------------------------------------------------------------------------------------------------ -// read an array of int64_ts -void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el) -{ - out.resize( 0 ); - const TokenList& tok = el.Tokens(); - if (tok.empty()) { - ParseError("unexpected empty element", &el); - } - - if (tok[0]->IsBinary()) { - const char* data = tok[0]->begin(), *end = tok[0]->end(); - - char type; - uint32_t count; - ReadBinaryDataArrayHead(data, end, type, count, el); - - if (!count) { - return; - } - - if (type != 'l') { - ParseError("expected long array (binary)", &el); - } - - std::vector<char> buff; - ReadBinaryDataArray(type, count, data, end, buff, el); - - ai_assert(data == end); - ai_assert(buff.size() == count * 8); - - out.reserve(count); - - const int64_t* ip = reinterpret_cast<const int64_t*>(&buff[0]); - for (unsigned int i = 0; i < count; ++i, ++ip) { - BE_NCONST int64_t val = *ip; - AI_SWAP8(val); - out.push_back(val); - } - - return; - } - - const size_t dim = ParseTokenAsDim(*tok[0]); - - // see notes in ParseVectorDataArray() - out.reserve(dim); - - const Scope& scope = GetRequiredScope(el); - const Element& a = GetRequiredElement(scope, "a", &el); - - for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) { - const int64_t ival = ParseTokenAsInt64(**it++); - - out.push_back(ival); - } -} - -// ------------------------------------------------------------------------------------------------ -aiMatrix4x4 ReadMatrix(const Element& element) -{ - std::vector<float> values; - ParseVectorDataArray(values,element); - - if(values.size() != 16) { - ParseError("expected 16 matrix elements"); - } - - aiMatrix4x4 result; - - - result.a1 = values[0]; - result.a2 = values[1]; - result.a3 = values[2]; - result.a4 = values[3]; - - result.b1 = values[4]; - result.b2 = values[5]; - result.b3 = values[6]; - result.b4 = values[7]; - - result.c1 = values[8]; - result.c2 = values[9]; - result.c3 = values[10]; - result.c4 = values[11]; - - result.d1 = values[12]; - result.d2 = values[13]; - result.d3 = values[14]; - result.d4 = values[15]; - - result.Transpose(); - return result; -} - - -// ------------------------------------------------------------------------------------------------ -// wrapper around ParseTokenAsString() with ParseError handling -std::string ParseTokenAsString(const Token& t) -{ - const char* err; - const std::string& i = ParseTokenAsString(t,err); - if(err) { - ParseError(err,t); - } - return i; -} - -bool HasElement( const Scope& sc, const std::string& index ) { - const Element* el = sc[ index ]; - if ( nullptr == el ) { - return false; - } - - return true; -} - -// ------------------------------------------------------------------------------------------------ -// extract a required element from a scope, abort if the element cannot be found -const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= NULL*/) -{ - const Element* el = sc[index]; - if(!el) { - ParseError("did not find required element \"" + index + "\"",element); - } - return *el; -} - - -// ------------------------------------------------------------------------------------------------ -// extract required compound scope -const Scope& GetRequiredScope(const Element& el) -{ - const Scope* const s = el.Compound(); - if(!s) { - ParseError("expected compound scope",&el); - } - - return *s; -} - - -// ------------------------------------------------------------------------------------------------ -// get token at a particular index -const Token& GetRequiredToken(const Element& el, unsigned int index) -{ - const TokenList& t = el.Tokens(); - if(index >= t.size()) { - ParseError(Formatter::format( "missing token at index " ) << index,&el); - } - - return *t[index]; -} - - -// ------------------------------------------------------------------------------------------------ -// wrapper around ParseTokenAsID() with ParseError handling -uint64_t ParseTokenAsID(const Token& t) -{ - const char* err; - const uint64_t i = ParseTokenAsID(t,err); - if(err) { - ParseError(err,t); - } - return i; -} - - -// ------------------------------------------------------------------------------------------------ -// wrapper around ParseTokenAsDim() with ParseError handling -size_t ParseTokenAsDim(const Token& t) -{ - const char* err; - const size_t i = ParseTokenAsDim(t,err); - if(err) { - ParseError(err,t); - } - return i; -} - - -// ------------------------------------------------------------------------------------------------ -// wrapper around ParseTokenAsFloat() with ParseError handling -float ParseTokenAsFloat(const Token& t) -{ - const char* err; - const float i = ParseTokenAsFloat(t,err); - if(err) { - ParseError(err,t); - } - return i; -} - -// ------------------------------------------------------------------------------------------------ -// wrapper around ParseTokenAsInt() with ParseError handling -int ParseTokenAsInt(const Token& t) -{ - const char* err; - const int i = ParseTokenAsInt(t,err); - if(err) { - ParseError(err,t); - } - return i; -} - -// ------------------------------------------------------------------------------------------------ -// wrapper around ParseTokenAsInt64() with ParseError handling -int64_t ParseTokenAsInt64(const Token& t) -{ - const char* err; - const int64_t i = ParseTokenAsInt64(t, err); - if (err) { - ParseError(err, t); - } - return i; -} - -} // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXParser.h b/thirdparty/assimp/code/FBX/FBXParser.h deleted file mode 100644 index 7b0cf72039..0000000000 --- a/thirdparty/assimp/code/FBX/FBXParser.h +++ /dev/null @@ -1,235 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXParser.h - * @brief FBX parsing code - */ -#ifndef INCLUDED_AI_FBX_PARSER_H -#define INCLUDED_AI_FBX_PARSER_H - -#include <stdint.h> -#include <map> -#include <memory> -#include <assimp/LogAux.h> -#include <assimp/fast_atof.h> - -#include "FBXCompileConfig.h" -#include "FBXTokenizer.h" - -namespace Assimp { -namespace FBX { - -class Scope; -class Parser; -class Element; - -// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03 -typedef std::vector< Scope* > ScopeList; -typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap; - -typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection; - -# define new_Scope new Scope -# define new_Element new Element - - -/** FBX data entity that consists of a key:value tuple. - * - * Example: - * @verbatim - * AnimationCurve: 23, "AnimCurve::", "" { - * [..] - * } - * @endverbatim - * - * As can be seen in this sample, elements can contain nested #Scope - * as their trailing member. **/ -class Element -{ -public: - Element(const Token& key_token, Parser& parser); - ~Element(); - - const Scope* Compound() const { - return compound.get(); - } - - const Token& KeyToken() const { - return key_token; - } - - const TokenList& Tokens() const { - return tokens; - } - -private: - const Token& key_token; - TokenList tokens; - std::unique_ptr<Scope> compound; -}; - -/** FBX data entity that consists of a 'scope', a collection - * of not necessarily unique #Element instances. - * - * Example: - * @verbatim - * GlobalSettings: { - * Version: 1000 - * Properties70: - * [...] - * } - * @endverbatim */ -class Scope -{ -public: - Scope(Parser& parser, bool topLevel = false); - ~Scope(); - - const Element* operator[] (const std::string& index) const { - ElementMap::const_iterator it = elements.find(index); - return it == elements.end() ? NULL : (*it).second; - } - - const Element* FindElementCaseInsensitive(const std::string& elementName) const { - const char* elementNameCStr = elementName.c_str(); - for (auto element = elements.begin(); element != elements.end(); ++element) - { - if (!ASSIMP_strincmp(element->first.c_str(), elementNameCStr, MAXLEN)) { - return element->second; - } - } - return NULL; - } - - ElementCollection GetCollection(const std::string& index) const { - return elements.equal_range(index); - } - - const ElementMap& Elements() const { - return elements; - } - -private: - ElementMap elements; -}; - -/** FBX parsing class, takes a list of input tokens and generates a hierarchy - * of nested #Scope instances, representing the fbx DOM.*/ -class Parser -{ -public: - /** Parse given a token list. Does not take ownership of the tokens - - * the objects must persist during the entire parser lifetime */ - Parser (const TokenList& tokens,bool is_binary); - ~Parser(); - - const Scope& GetRootScope() const { - return *root.get(); - } - - bool IsBinary() const { - return is_binary; - } - -private: - friend class Scope; - friend class Element; - - TokenPtr AdvanceToNextToken(); - TokenPtr LastToken() const; - TokenPtr CurrentToken() const; - -private: - const TokenList& tokens; - - TokenPtr last, current; - TokenList::const_iterator cursor; - std::unique_ptr<Scope> root; - - const bool is_binary; -}; - - -/* token parsing - this happens when building the DOM out of the parse-tree*/ -uint64_t ParseTokenAsID(const Token& t, const char*& err_out); -size_t ParseTokenAsDim(const Token& t, const char*& err_out); - -float ParseTokenAsFloat(const Token& t, const char*& err_out); -int ParseTokenAsInt(const Token& t, const char*& err_out); -int64_t ParseTokenAsInt64(const Token& t, const char*& err_out); -std::string ParseTokenAsString(const Token& t, const char*& err_out); - -/* wrapper around ParseTokenAsXXX() with DOMError handling */ -uint64_t ParseTokenAsID(const Token& t); -size_t ParseTokenAsDim(const Token& t); -float ParseTokenAsFloat(const Token& t); -int ParseTokenAsInt(const Token& t); -int64_t ParseTokenAsInt64(const Token& t); -std::string ParseTokenAsString(const Token& t); - -/* read data arrays */ -void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el); -void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el); -void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el); -void ParseVectorDataArray(std::vector<int>& out, const Element& el); -void ParseVectorDataArray(std::vector<float>& out, const Element& el); -void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el); -void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e); -void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el); - -bool HasElement( const Scope& sc, const std::string& index ); - -// extract a required element from a scope, abort if the element cannot be found -const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL); - -// extract required compound scope -const Scope& GetRequiredScope(const Element& el); -// get token at a particular index -const Token& GetRequiredToken(const Element& el, unsigned int index); - -// read a 4x4 matrix from an array of 16 floats -aiMatrix4x4 ReadMatrix(const Element& element); - -} // ! FBX -} // ! Assimp - -#endif // ! INCLUDED_AI_FBX_PARSER_H diff --git a/thirdparty/assimp/code/FBX/FBXProperties.cpp b/thirdparty/assimp/code/FBX/FBXProperties.cpp deleted file mode 100644 index 8d7036b6a9..0000000000 --- a/thirdparty/assimp/code/FBX/FBXProperties.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXProperties.cpp - * @brief Implementation of the FBX dynamic properties system - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -#include "FBXTokenizer.h" -#include "FBXParser.h" -#include "FBXDocument.h" -#include "FBXDocumentUtil.h" -#include "FBXProperties.h" - -namespace Assimp { -namespace FBX { - - using namespace Util; - -// ------------------------------------------------------------------------------------------------ -Property::Property() -{ -} - -// ------------------------------------------------------------------------------------------------ -Property::~Property() -{ -} - -namespace { - -// ------------------------------------------------------------------------------------------------ -// read a typed property out of a FBX element. The return value is NULL if the property cannot be read. -Property* ReadTypedProperty(const Element& element) -{ - ai_assert(element.KeyToken().StringContents() == "P"); - - const TokenList& tok = element.Tokens(); - ai_assert(tok.size() >= 5); - - const std::string& s = ParseTokenAsString(*tok[1]); - const char* const cs = s.c_str(); - if (!strcmp(cs,"KString")) { - return new TypedProperty<std::string>(ParseTokenAsString(*tok[4])); - } - else if (!strcmp(cs,"bool") || !strcmp(cs,"Bool")) { - return new TypedProperty<bool>(ParseTokenAsInt(*tok[4]) != 0); - } - else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) { - return new TypedProperty<int>(ParseTokenAsInt(*tok[4])); - } - else if (!strcmp(cs, "ULongLong")) { - return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4])); - } - else if (!strcmp(cs, "KTime")) { - return new TypedProperty<int64_t>(ParseTokenAsInt64(*tok[4])); - } - else if (!strcmp(cs,"Vector3D") || - !strcmp(cs,"ColorRGB") || - !strcmp(cs,"Vector") || - !strcmp(cs,"Color") || - !strcmp(cs,"Lcl Translation") || - !strcmp(cs,"Lcl Rotation") || - !strcmp(cs,"Lcl Scaling") - ) { - return new TypedProperty<aiVector3D>(aiVector3D( - ParseTokenAsFloat(*tok[4]), - ParseTokenAsFloat(*tok[5]), - ParseTokenAsFloat(*tok[6])) - ); - } - else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) { - return new TypedProperty<float>(ParseTokenAsFloat(*tok[4])); - } - return NULL; -} - - -// ------------------------------------------------------------------------------------------------ -// peek into an element and check if it contains a FBX property, if so return its name. -std::string PeekPropertyName(const Element& element) -{ - ai_assert(element.KeyToken().StringContents() == "P"); - const TokenList& tok = element.Tokens(); - if(tok.size() < 4) { - return ""; - } - - return ParseTokenAsString(*tok[0]); -} - -} //! anon - - -// ------------------------------------------------------------------------------------------------ -PropertyTable::PropertyTable() -: templateProps() -, element() -{ -} - -// ------------------------------------------------------------------------------------------------ -PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps) -: templateProps(templateProps) -, element(&element) -{ - const Scope& scope = GetRequiredScope(element); - for(const ElementMap::value_type& v : scope.Elements()) { - if(v.first != "P") { - DOMWarning("expected only P elements in property table",v.second); - continue; - } - - const std::string& name = PeekPropertyName(*v.second); - if(!name.length()) { - DOMWarning("could not read property name",v.second); - continue; - } - - LazyPropertyMap::const_iterator it = lazyProps.find(name); - if (it != lazyProps.end()) { - DOMWarning("duplicate property name, will hide previous value: " + name,v.second); - continue; - } - - lazyProps[name] = v.second; - } -} - - -// ------------------------------------------------------------------------------------------------ -PropertyTable::~PropertyTable() -{ - for(PropertyMap::value_type& v : props) { - delete v.second; - } -} - - -// ------------------------------------------------------------------------------------------------ -const Property* PropertyTable::Get(const std::string& name) const -{ - PropertyMap::const_iterator it = props.find(name); - if (it == props.end()) { - // hasn't been parsed yet? - LazyPropertyMap::const_iterator lit = lazyProps.find(name); - if(lit != lazyProps.end()) { - props[name] = ReadTypedProperty(*(*lit).second); - it = props.find(name); - - ai_assert(it != props.end()); - } - - if (it == props.end()) { - // check property template - if(templateProps) { - return templateProps->Get(name); - } - - return NULL; - } - } - - return (*it).second; -} - -DirectPropertyMap PropertyTable::GetUnparsedProperties() const -{ - DirectPropertyMap result; - - // Loop through all the lazy properties (which is all the properties) - for(const LazyPropertyMap::value_type& element : lazyProps) { - - // Skip parsed properties - if (props.end() != props.find(element.first)) continue; - - // Read the element's value. - // Wrap the naked pointer (since the call site is required to acquire ownership) - // std::unique_ptr from C++11 would be preferred both as a wrapper and a return value. - std::shared_ptr<Property> prop = std::shared_ptr<Property>(ReadTypedProperty(*element.second)); - - // Element could not be read. Skip it. - if (!prop) continue; - - // Add to result - result[element.first] = prop; - } - - return result; -} - -} //! FBX -} //! Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXProperties.h b/thirdparty/assimp/code/FBX/FBXProperties.h deleted file mode 100644 index 58755542fc..0000000000 --- a/thirdparty/assimp/code/FBX/FBXProperties.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXProperties.h - * @brief FBX dynamic properties - */ -#ifndef INCLUDED_AI_FBX_PROPERTIES_H -#define INCLUDED_AI_FBX_PROPERTIES_H - -#include "FBXCompileConfig.h" -#include <memory> -#include <string> - -namespace Assimp { -namespace FBX { - -// Forward declarations -class Element; - -/** Represents a dynamic property. Type info added by deriving classes, - * see #TypedProperty. - Example: - @verbatim - P: "ShininessExponent", "double", "Number", "",0.5 - @endvebatim -*/ -class Property { -protected: - Property(); - -public: - virtual ~Property(); - -public: - template <typename T> - const T* As() const { - return dynamic_cast<const T*>(this); - } -}; - -template<typename T> -class TypedProperty : public Property { -public: - explicit TypedProperty(const T& value) - : value(value) { - // empty - } - - const T& Value() const { - return value; - } - -private: - T value; -}; - - -typedef std::fbx_unordered_map<std::string,std::shared_ptr<Property> > DirectPropertyMap; -typedef std::fbx_unordered_map<std::string,const Property*> PropertyMap; -typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap; - -/** - * Represents a property table as can be found in the newer FBX files (Properties60, Properties70) - */ -class PropertyTable { -public: - // in-memory property table with no source element - PropertyTable(); - PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps); - ~PropertyTable(); - - const Property* Get(const std::string& name) const; - - // PropertyTable's need not be coupled with FBX elements so this can be NULL - const Element* GetElement() const { - return element; - } - - const PropertyTable* TemplateProps() const { - return templateProps.get(); - } - - DirectPropertyMap GetUnparsedProperties() const; - -private: - LazyPropertyMap lazyProps; - mutable PropertyMap props; - const std::shared_ptr<const PropertyTable> templateProps; - const Element* const element; -}; - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) { - const Property* const prop = in.Get(name); - if( nullptr == prop) { - return defaultValue; - } - - // strong typing, no need to be lenient - const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >(); - if( nullptr == tprop) { - return defaultValue; - } - - return tprop->Value(); -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) { - const Property* prop = in.Get(name); - if( nullptr == prop) { - if ( ! useTemplate ) { - result = false; - return T(); - } - const PropertyTable* templ = in.TemplateProps(); - if ( nullptr == templ ) { - result = false; - return T(); - } - prop = templ->Get(name); - if ( nullptr == prop ) { - result = false; - return T(); - } - } - - // strong typing, no need to be lenient - const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >(); - if( nullptr == tprop) { - result = false; - return T(); - } - - result = true; - return tprop->Value(); -} - -} //! FBX -} //! Assimp - -#endif // INCLUDED_AI_FBX_PROPERTIES_H diff --git a/thirdparty/assimp/code/FBX/FBXTokenizer.cpp b/thirdparty/assimp/code/FBX/FBXTokenizer.cpp deleted file mode 100644 index 252cce3557..0000000000 --- a/thirdparty/assimp/code/FBX/FBXTokenizer.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXTokenizer.cpp - * @brief Implementation of the FBX broadphase lexer - */ - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -// tab width for logging columns -#define ASSIMP_FBX_TAB_WIDTH 4 - -#include <assimp/ParsingUtils.h> - -#include "FBXTokenizer.h" -#include "FBXUtil.h" -#include <assimp/Exceptional.h> - -namespace Assimp { -namespace FBX { - -// ------------------------------------------------------------------------------------------------ -Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column) - : -#ifdef DEBUG - contents(sbegin, static_cast<size_t>(send-sbegin)), -#endif - sbegin(sbegin) - , send(send) - , type(type) - , line(line) - , column(column) -{ - ai_assert(sbegin); - ai_assert(send); - - // tokens must be of non-zero length - ai_assert(static_cast<size_t>(send-sbegin) > 0); -} - -// ------------------------------------------------------------------------------------------------ -Token::~Token() -{ -} - -namespace { - -// ------------------------------------------------------------------------------------------------ -// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError. -AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line, unsigned int column) AI_WONT_RETURN_SUFFIX; -AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line, unsigned int column) -{ - throw DeadlyImportError(Util::AddLineAndColumn("FBX-Tokenize",message,line,column)); -} - - -// process a potential data token up to 'cur', adding it to 'output_tokens'. -// ------------------------------------------------------------------------------------------------ -void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*& end, - unsigned int line, - unsigned int column, - TokenType type = TokenType_DATA, - bool must_have_token = false) -{ - if (start && end) { - // sanity check: - // tokens should have no whitespace outside quoted text and [start,end] should - // properly delimit the valid range. - bool in_double_quotes = false; - for (const char* c = start; c != end + 1; ++c) { - if (*c == '\"') { - in_double_quotes = !in_double_quotes; - } - - if (!in_double_quotes && IsSpaceOrNewLine(*c)) { - TokenizeError("unexpected whitespace in token", line, column); - } - } - - if (in_double_quotes) { - TokenizeError("non-terminated double quotes", line, column); - } - - output_tokens.push_back(new_Token(start,end + 1,type,line,column)); - } - else if (must_have_token) { - TokenizeError("unexpected character, expected data token", line, column); - } - - start = end = NULL; -} - -} - -// ------------------------------------------------------------------------------------------------ -void Tokenize(TokenList& output_tokens, const char* input) -{ - ai_assert(input); - - // line and column numbers numbers are one-based - unsigned int line = 1; - unsigned int column = 1; - - bool comment = false; - bool in_double_quotes = false; - bool pending_data_token = false; - - const char* token_begin = NULL, *token_end = NULL; - for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) { - const char c = *cur; - - if (IsLineEnd(c)) { - comment = false; - - column = 0; - ++line; - } - - if(comment) { - continue; - } - - if(in_double_quotes) { - if (c == '\"') { - in_double_quotes = false; - token_end = cur; - - ProcessDataToken(output_tokens,token_begin,token_end,line,column); - pending_data_token = false; - } - continue; - } - - switch(c) - { - case '\"': - if (token_begin) { - TokenizeError("unexpected double-quote", line, column); - } - token_begin = cur; - in_double_quotes = true; - continue; - - case ';': - ProcessDataToken(output_tokens,token_begin,token_end,line,column); - comment = true; - continue; - - case '{': - ProcessDataToken(output_tokens,token_begin,token_end, line, column); - output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column)); - continue; - - case '}': - ProcessDataToken(output_tokens,token_begin,token_end,line,column); - output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column)); - continue; - - case ',': - if (pending_data_token) { - ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_DATA,true); - } - output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column)); - continue; - - case ':': - if (pending_data_token) { - ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_KEY,true); - } - else { - TokenizeError("unexpected colon", line, column); - } - continue; - } - - if (IsSpaceOrNewLine(c)) { - - if (token_begin) { - // peek ahead and check if the next token is a colon in which - // case this counts as KEY token. - TokenType type = TokenType_DATA; - for (const char* peek = cur; *peek && IsSpaceOrNewLine(*peek); ++peek) { - if (*peek == ':') { - type = TokenType_KEY; - cur = peek; - break; - } - } - - ProcessDataToken(output_tokens,token_begin,token_end,line,column,type); - } - - pending_data_token = false; - } - else { - token_end = cur; - if (!token_begin) { - token_begin = cur; - } - - pending_data_token = true; - } - } -} - -} // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXTokenizer.h b/thirdparty/assimp/code/FBX/FBXTokenizer.h deleted file mode 100644 index afa588a470..0000000000 --- a/thirdparty/assimp/code/FBX/FBXTokenizer.h +++ /dev/null @@ -1,187 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXTokenizer.h - * @brief FBX lexer - */ -#ifndef INCLUDED_AI_FBX_TOKENIZER_H -#define INCLUDED_AI_FBX_TOKENIZER_H - -#include "FBXCompileConfig.h" -#include <assimp/ai_assert.h> -#include <vector> -#include <string> - -namespace Assimp { -namespace FBX { - -/** Rough classification for text FBX tokens used for constructing the - * basic scope hierarchy. */ -enum TokenType -{ - // { - TokenType_OPEN_BRACKET = 0, - - // } - TokenType_CLOSE_BRACKET, - - // '"blablubb"', '2', '*14' - very general token class, - // further processing happens at a later stage. - TokenType_DATA, - - // - TokenType_BINARY_DATA, - - // , - TokenType_COMMA, - - // blubb: - TokenType_KEY -}; - - -/** Represents a single token in a FBX file. Tokens are - * classified by the #TokenType enumerated types. - * - * Offers iterator protocol. Tokens are immutable. */ -class Token -{ -private: - static const unsigned int BINARY_MARKER = static_cast<unsigned int>(-1); - -public: - /** construct a textual token */ - Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column); - - /** construct a binary token */ - Token(const char* sbegin, const char* send, TokenType type, size_t offset); - - ~Token(); - -public: - std::string StringContents() const { - return std::string(begin(),end()); - } - - bool IsBinary() const { - return column == BINARY_MARKER; - } - - const char* begin() const { - return sbegin; - } - - const char* end() const { - return send; - } - - TokenType Type() const { - return type; - } - - size_t Offset() const { - ai_assert(IsBinary()); - return offset; - } - - unsigned int Line() const { - ai_assert(!IsBinary()); - return static_cast<unsigned int>(line); - } - - unsigned int Column() const { - ai_assert(!IsBinary()); - return column; - } - -private: - -#ifdef DEBUG - // full string copy for the sole purpose that it nicely appears - // in msvc's debugger window. - const std::string contents; -#endif - - - const char* const sbegin; - const char* const send; - const TokenType type; - - union { - size_t line; - size_t offset; - }; - const unsigned int column; -}; - -// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03 -typedef const Token* TokenPtr; -typedef std::vector< TokenPtr > TokenList; - -#define new_Token new Token - - -/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens. - * - * Skips over comments and generates line and column numbers. - * - * @param output_tokens Receives a list of all tokens in the input data. - * @param input_buffer Textual input buffer to be processed, 0-terminated. - * @throw DeadlyImportError if something goes wrong */ -void Tokenize(TokenList& output_tokens, const char* input); - - -/** Tokenizer function for binary FBX files. - * - * Emits a token list suitable for direct parsing. - * - * @param output_tokens Receives a list of all tokens in the input data. - * @param input_buffer Binary input buffer to be processed. - * @param length Length of input buffer, in bytes. There is no 0-terminal. - * @throw DeadlyImportError if something goes wrong */ -void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length); - - -} // ! FBX -} // ! Assimp - -#endif // ! INCLUDED_AI_FBX_PARSER_H diff --git a/thirdparty/assimp/code/FBX/FBXUtil.cpp b/thirdparty/assimp/code/FBX/FBXUtil.cpp deleted file mode 100644 index c10e057c8c..0000000000 --- a/thirdparty/assimp/code/FBX/FBXUtil.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXUtil.cpp - * @brief Implementation of internal FBX utility functions - */ - -#include "FBXUtil.h" -#include "FBXTokenizer.h" - -#include <assimp/TinyFormatter.h> -#include <string> -#include <cstring> - -#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER - -namespace Assimp { -namespace FBX { -namespace Util { - -// ------------------------------------------------------------------------------------------------ -const char* TokenTypeString(TokenType t) -{ - switch(t) { - case TokenType_OPEN_BRACKET: - return "TOK_OPEN_BRACKET"; - - case TokenType_CLOSE_BRACKET: - return "TOK_CLOSE_BRACKET"; - - case TokenType_DATA: - return "TOK_DATA"; - - case TokenType_COMMA: - return "TOK_COMMA"; - - case TokenType_KEY: - return "TOK_KEY"; - - case TokenType_BINARY_DATA: - return "TOK_BINARY_DATA"; - } - - ai_assert(false); - return ""; -} - - -// ------------------------------------------------------------------------------------------------ -std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset) -{ - return static_cast<std::string>( (Formatter::format() << prefix << " (offset 0x" << std::hex << offset << ") " << text) ); -} - -// ------------------------------------------------------------------------------------------------ -std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column) -{ - return static_cast<std::string>( (Formatter::format() << prefix << " (line " << line << " << col " << column << ") " << text) ); -} - -// ------------------------------------------------------------------------------------------------ -std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok) -{ - if(tok->IsBinary()) { - return static_cast<std::string>( (Formatter::format() << prefix << - " (" << TokenTypeString(tok->Type()) << - ", offset 0x" << std::hex << tok->Offset() << ") " << - text) ); - } - - return static_cast<std::string>( (Formatter::format() << prefix << - " (" << TokenTypeString(tok->Type()) << - ", line " << tok->Line() << - ", col " << tok->Column() << ") " << - text) ); -} - -// Generated by this formula: T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i; -static const uint8_t base64DecodeTable[128] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255, - 255, 0, 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, 255, 255, 255, 255, 255, - 255, 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, 255, 255, 255, 255, 255 -}; - -uint8_t DecodeBase64(char ch) -{ - const auto idx = static_cast<uint8_t>(ch); - if (idx > 127) - return 255; - return base64DecodeTable[idx]; -} - -size_t ComputeDecodedSizeBase64(const char* in, size_t inLength) -{ - if (inLength < 2) - { - return 0; - } - const size_t equals = size_t(in[inLength - 1] == '=') + size_t(in[inLength - 2] == '='); - const size_t full_length = (inLength * 3) >> 2; // div by 4 - if (full_length < equals) - { - return 0; - } - return full_length - equals; -} - -size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOutLength) -{ - if (maxOutLength == 0 || inLength < 2) { - return 0; - } - const size_t realLength = inLength - size_t(in[inLength - 1] == '=') - size_t(in[inLength - 2] == '='); - size_t dst_offset = 0; - int val = 0, valb = -8; - for (size_t src_offset = 0; src_offset < realLength; ++src_offset) - { - const uint8_t table_value = Util::DecodeBase64(in[src_offset]); - if (table_value == 255) - { - return 0; - } - val = (val << 6) + table_value; - valb += 6; - if (valb >= 0) - { - out[dst_offset++] = static_cast<uint8_t>((val >> valb) & 0xFF); - valb -= 8; - val &= 0xFFF; - } - } - return dst_offset; -} - -static const char to_base64_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -char EncodeBase64(char byte) -{ - return to_base64_string[(size_t)byte]; -} - -/** Encodes a block of 4 bytes to base64 encoding -* -* @param bytes Bytes to encode. -* @param out_string String to write encoded values to. -* @param string_pos Position in out_string.*/ -void EncodeByteBlock(const char* bytes, std::string& out_string, size_t string_pos) -{ - char b0 = (bytes[0] & 0xFC) >> 2; - char b1 = (bytes[0] & 0x03) << 4 | ((bytes[1] & 0xF0) >> 4); - char b2 = (bytes[1] & 0x0F) << 2 | ((bytes[2] & 0xC0) >> 6); - char b3 = (bytes[2] & 0x3F); - - out_string[string_pos + 0] = EncodeBase64(b0); - out_string[string_pos + 1] = EncodeBase64(b1); - out_string[string_pos + 2] = EncodeBase64(b2); - out_string[string_pos + 3] = EncodeBase64(b3); -} - -std::string EncodeBase64(const char* data, size_t length) -{ - // calculate extra bytes needed to get a multiple of 3 - size_t extraBytes = 3 - length % 3; - - // number of base64 bytes - size_t encodedBytes = 4 * (length + extraBytes) / 3; - - std::string encoded_string(encodedBytes, '='); - - // read blocks of 3 bytes - for (size_t ib3 = 0; ib3 < length / 3; ib3++) - { - const size_t iByte = ib3 * 3; - const size_t iEncodedByte = ib3 * 4; - const char* currData = &data[iByte]; - - EncodeByteBlock(currData, encoded_string, iEncodedByte); - } - - // if size of data is not a multiple of 3, also encode the final bytes (and add zeros where needed) - if (extraBytes > 0) - { - char finalBytes[4] = { 0,0,0,0 }; - memcpy(&finalBytes[0], &data[length - length % 3], length % 3); - - const size_t iEncodedByte = encodedBytes - 4; - EncodeByteBlock(&finalBytes[0], encoded_string, iEncodedByte); - - // add '=' at the end - for (size_t i = 0; i < 4 * extraBytes / 3; i++) - encoded_string[encodedBytes - i - 1] = '='; - } - return encoded_string; -} - -} // !Util -} // !FBX -} // !Assimp - -#endif diff --git a/thirdparty/assimp/code/FBX/FBXUtil.h b/thirdparty/assimp/code/FBX/FBXUtil.h deleted file mode 100644 index b634418858..0000000000 --- a/thirdparty/assimp/code/FBX/FBXUtil.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FBXUtil.h - * @brief FBX utility functions for internal use - */ -#ifndef INCLUDED_AI_FBX_UTIL_H -#define INCLUDED_AI_FBX_UTIL_H - -#include "FBXCompileConfig.h" -#include "FBXTokenizer.h" -#include <stdint.h> - -namespace Assimp { -namespace FBX { - - -namespace Util { - - -/** helper for std::for_each to delete all heap-allocated items in a container */ -template<typename T> -struct delete_fun -{ - void operator()(const volatile T* del) { - delete del; - } -}; - -/** Get a string representation for a #TokenType. */ -const char* TokenTypeString(TokenType t); - - - -/** Format log/error messages using a given offset in the source binary file - * - * @param prefix Message prefix to be preprended to the location info. - * @param text Message text - * @param line Line index, 1-based - * @param column Column index, 1-based - * @return A string of the following format: {prefix} (offset 0x{offset}) {text}*/ -std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset); - - -/** Format log/error messages using a given line location in the source file. - * - * @param prefix Message prefix to be preprended to the location info. - * @param text Message text - * @param line Line index, 1-based - * @param column Column index, 1-based - * @return A string of the following format: {prefix} (line {line}, col {column}) {text}*/ -std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column); - - -/** Format log/error messages using a given cursor token. - * - * @param prefix Message prefix to be preprended to the location info. - * @param text Message text - * @param tok Token where parsing/processing stopped - * @return A string of the following format: {prefix} ({token-type}, line {line}, col {column}) {text}*/ -std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok); - -/** Decode a single Base64-encoded character. -* -* @param ch Character to decode (from base64 to binary). -* @return decoded byte value*/ -uint8_t DecodeBase64(char ch); - -/** Compute decoded size of a Base64-encoded string -* -* @param in Characters to decode. -* @param inLength Number of characters to decode. -* @return size of the decoded data (number of bytes)*/ -size_t ComputeDecodedSizeBase64(const char* in, size_t inLength); - -/** Decode a Base64-encoded string -* -* @param in Characters to decode. -* @param inLength Number of characters to decode. -* @param out Pointer where we will store the decoded data. -* @param maxOutLength Size of output buffer. -* @return size of the decoded data (number of bytes)*/ -size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOutLength); - -char EncodeBase64(char byte); - -/** Encode bytes in base64-encoding -* -* @param data Binary data to encode. -* @param inLength Number of bytes to encode. -* @return base64-encoded string*/ -std::string EncodeBase64(const char* data, size_t length); - -} -} -} - -#endif // ! INCLUDED_AI_FBX_UTIL_H diff --git a/thirdparty/assimp/code/Material/MaterialSystem.cpp b/thirdparty/assimp/code/Material/MaterialSystem.cpp deleted file mode 100644 index 0be6e9f7bb..0000000000 --- a/thirdparty/assimp/code/Material/MaterialSystem.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file MaterialSystem.cpp - * @brief Implementation of the material system of the library - */ - -#include <assimp/Hash.h> -#include <assimp/fast_atof.h> -#include <assimp/ParsingUtils.h> -#include "MaterialSystem.h" -#include <assimp/types.h> -#include <assimp/material.h> -#include <assimp/DefaultLogger.hpp> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Get a specific property from a material -aiReturn aiGetMaterialProperty(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - const aiMaterialProperty** pPropOut) -{ - ai_assert( pMat != NULL ); - ai_assert( pKey != NULL ); - ai_assert( pPropOut != NULL ); - - /* Just search for a property with exactly this name .. - * could be improved by hashing, but it's possibly - * no worth the effort (we're bound to C structures, - * thus std::map or derivates are not applicable. */ - for ( unsigned int i = 0; i < pMat->mNumProperties; ++i ) { - aiMaterialProperty* prop = pMat->mProperties[i]; - - if (prop /* just for safety ... */ - && 0 == strcmp( prop->mKey.data, pKey ) - && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */ - && (UINT_MAX == index || prop->mIndex == index)) - { - *pPropOut = pMat->mProperties[i]; - return AI_SUCCESS; - } - } - *pPropOut = NULL; - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -// Get an array of floating-point values from the material. -aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - ai_real* pOut, - unsigned int* pMax) -{ - ai_assert( pOut != nullptr ); - ai_assert( pMat != nullptr ); - - const aiMaterialProperty* prop; - aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop); - if ( nullptr == prop) { - return AI_FAILURE; - } - - // data is given in floats, convert to ai_real - unsigned int iWrite = 0; - if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) { - iWrite = prop->mDataLength / sizeof(float); - if (pMax) { - iWrite = std::min(*pMax,iWrite); ; - } - - for (unsigned int a = 0; a < iWrite; ++a) { - pOut[ a ] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] ); - } - - if (pMax) { - *pMax = iWrite; - } - } - // data is given in doubles, convert to float - else if( aiPTI_Double == prop->mType) { - iWrite = prop->mDataLength / sizeof(double); - if (pMax) { - iWrite = std::min(*pMax,iWrite); ; - } - for (unsigned int a = 0; a < iWrite;++a) { - pOut[a] = static_cast<ai_real> ( reinterpret_cast<double*>(prop->mData)[a] ); - } - if (pMax) { - *pMax = iWrite; - } - } - // data is given in ints, convert to float - else if( aiPTI_Integer == prop->mType) { - iWrite = prop->mDataLength / sizeof(int32_t); - if (pMax) { - iWrite = std::min(*pMax,iWrite); ; - } - for (unsigned int a = 0; a < iWrite;++a) { - pOut[a] = static_cast<ai_real> ( reinterpret_cast<int32_t*>(prop->mData)[a] ); - } - if (pMax) { - *pMax = iWrite; - } - } - // a string ... read floats separated by spaces - else { - if (pMax) { - iWrite = *pMax; - } - // strings are zero-terminated with a 32 bit length prefix, so this is safe - const char *cur = prop->mData + 4; - ai_assert( prop->mDataLength >= 5 ); - ai_assert( !prop->mData[ prop->mDataLength - 1 ] ); - for ( unsigned int a = 0; ;++a) { - cur = fast_atoreal_move<ai_real>(cur,pOut[a]); - if ( a==iWrite-1 ) { - break; - } - if ( !IsSpace(*cur) ) { - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + - " is a string; failed to parse a float array out of it."); - return AI_FAILURE; - } - } - - if (pMax) { - *pMax = iWrite; - } - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get an array if integers from the material -aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - int* pOut, - unsigned int* pMax) -{ - ai_assert( pOut != NULL ); - ai_assert( pMat != NULL ); - - const aiMaterialProperty* prop; - aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop); - if (!prop) { - return AI_FAILURE; - } - - // data is given in ints, simply copy it - unsigned int iWrite = 0; - if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) { - iWrite = std::max(static_cast<unsigned int>(prop->mDataLength / sizeof(int32_t)), 1u); - if (pMax) { - iWrite = std::min(*pMax,iWrite); - } - if (1 == prop->mDataLength) { - // bool type, 1 byte - *pOut = static_cast<int>(*prop->mData); - } - else { - for (unsigned int a = 0; a < iWrite;++a) { - pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]); - } - } - if (pMax) { - *pMax = iWrite; - } - } - // data is given in floats convert to int - else if( aiPTI_Float == prop->mType) { - iWrite = prop->mDataLength / sizeof(float); - if (pMax) { - iWrite = std::min(*pMax,iWrite); ; - } - for (unsigned int a = 0; a < iWrite;++a) { - pOut[a] = static_cast<int>(reinterpret_cast<float*>(prop->mData)[a]); - } - if (pMax) { - *pMax = iWrite; - } - } - // it is a string ... no way to read something out of this - else { - if (pMax) { - iWrite = *pMax; - } - // strings are zero-terminated with a 32 bit length prefix, so this is safe - const char *cur = prop->mData+4; - ai_assert( prop->mDataLength >= 5 ); - ai_assert( !prop->mData[ prop->mDataLength - 1 ] ); - for (unsigned int a = 0; ;++a) { - pOut[a] = strtol10(cur,&cur); - if(a==iWrite-1) { - break; - } - if(!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + - " is a string; failed to parse an integer array out of it."); - return AI_FAILURE; - } - } - - if (pMax) { - *pMax = iWrite; - } - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get a color (3 or 4 floats) from the material -aiReturn aiGetMaterialColor(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - aiColor4D* pOut) -{ - unsigned int iMax = 4; - const aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax); - - // if no alpha channel is defined: set it to 1.0 - if (3 == iMax) { - pOut->a = 1.0; - } - - return eRet; -} - -// ------------------------------------------------------------------------------------------------ -// Get a aiUVTransform (4 floats) from the material -aiReturn aiGetMaterialUVTransform(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - aiUVTransform* pOut) -{ - unsigned int iMax = 4; - return aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax); -} - -// ------------------------------------------------------------------------------------------------ -// Get a string from the material -aiReturn aiGetMaterialString(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - aiString* pOut) -{ - ai_assert (pOut != NULL); - - const aiMaterialProperty* prop; - aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**)&prop); - if (!prop) { - return AI_FAILURE; - } - - if( aiPTI_String == prop->mType) { - ai_assert(prop->mDataLength>=5); - - // The string is stored as 32 but length prefix followed by zero-terminated UTF8 data - pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData)); - - ai_assert( pOut->length+1+4==prop->mDataLength ); - ai_assert( !prop->mData[ prop->mDataLength - 1 ] ); - memcpy(pOut->data,prop->mData+4,pOut->length+1); - } - else { - // TODO - implement lexical cast as well - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + - " was found, but is no string" ); - return AI_FAILURE; - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get the number of textures on a particular texture stack -unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat, - C_ENUM aiTextureType type) -{ - ai_assert (pMat != NULL); - - // Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again) - unsigned int max = 0; - for (unsigned int i = 0; i < pMat->mNumProperties;++i) { - aiMaterialProperty* prop = pMat->mProperties[i]; - - if ( prop /* just a sanity check ... */ - && 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE ) - && prop->mSemantic == type) { - - max = std::max(max,prop->mIndex+1); - } - } - return max; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, - aiTextureType type, - unsigned int index, - C_STRUCT aiString* path, - aiTextureMapping* _mapping /*= NULL*/, - unsigned int* uvindex /*= NULL*/, - ai_real* blend /*= NULL*/, - aiTextureOp* op /*= NULL*/, - aiTextureMapMode* mapmode /*= NULL*/, - unsigned int* flags /*= NULL*/ - ) -{ - ai_assert( NULL != mat ); - ai_assert( NULL != path ); - - // Get the path to the texture - if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) { - return AI_FAILURE; - } - - // Determine mapping type - int mapping_ = static_cast<int>(aiTextureMapping_UV); - aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_); - aiTextureMapping mapping = static_cast<aiTextureMapping>(mapping_); - if (_mapping) - *_mapping = mapping; - - // Get UV index - if (aiTextureMapping_UV == mapping && uvindex) { - aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex); - } - // Get blend factor - if (blend) { - aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend); - } - // Get texture operation - if (op){ - aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op); - } - // Get texture mapping modes - if (mapmode) { - aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]); - aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]); - } - // Get texture flags - if (flags){ - aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags); - } - - return AI_SUCCESS; -} - - -static const unsigned int DefaultNumAllocated = 5; - -// ------------------------------------------------------------------------------------------------ -// Construction. Actually the one and only way to get an aiMaterial instance -aiMaterial::aiMaterial() -: mProperties( nullptr ) -, mNumProperties( 0 ) -, mNumAllocated( DefaultNumAllocated ) { - // Allocate 5 entries by default - mProperties = new aiMaterialProperty*[ DefaultNumAllocated ]; -} - -// ------------------------------------------------------------------------------------------------ -aiMaterial::~aiMaterial() -{ - Clear(); - - delete[] mProperties; -} - -// ------------------------------------------------------------------------------------------------ -aiString aiMaterial::GetName() { - aiString name; - Get(AI_MATKEY_NAME, name); - - return name; -} - -// ------------------------------------------------------------------------------------------------ -void aiMaterial::Clear() -{ - for ( unsigned int i = 0; i < mNumProperties; ++i ) { - // delete this entry - delete mProperties[ i ]; - AI_DEBUG_INVALIDATE_PTR(mProperties[i]); - } - mNumProperties = 0; - - // The array remains allocated, we just invalidated its contents -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsigned int index ) -{ - ai_assert( nullptr != pKey ); - - for (unsigned int i = 0; i < mNumProperties;++i) { - aiMaterialProperty* prop = mProperties[i]; - - if (prop && !strcmp( prop->mKey.data, pKey ) && - prop->mSemantic == type && prop->mIndex == index) - { - // Delete this entry - delete mProperties[i]; - - // collapse the array behind --. - --mNumProperties; - for (unsigned int a = i; a < mNumProperties;++a) { - mProperties[a] = mProperties[a+1]; - } - return AI_SUCCESS; - } - } - - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiMaterial::AddBinaryProperty (const void* pInput, - unsigned int pSizeInBytes, - const char* pKey, - unsigned int type, - unsigned int index, - aiPropertyTypeInfo pType - ) -{ - ai_assert( pInput != NULL ); - ai_assert( pKey != NULL ); - ai_assert( 0 != pSizeInBytes ); - - if ( 0 == pSizeInBytes ) { - - } - - // first search the list whether there is already an entry with this key - unsigned int iOutIndex( UINT_MAX ); - for ( unsigned int i = 0; i < mNumProperties; ++i ) { - aiMaterialProperty *prop( mProperties[ i ] ); - - if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) && - prop->mSemantic == type && prop->mIndex == index){ - - delete mProperties[i]; - iOutIndex = i; - } - } - - // Allocate a new material property - aiMaterialProperty* pcNew = new aiMaterialProperty(); - - // .. and fill it - pcNew->mType = pType; - pcNew->mSemantic = type; - pcNew->mIndex = index; - - pcNew->mDataLength = pSizeInBytes; - pcNew->mData = new char[pSizeInBytes]; - memcpy (pcNew->mData,pInput,pSizeInBytes); - - pcNew->mKey.length = ::strlen(pKey); - ai_assert ( MAXLEN > pcNew->mKey.length); - strcpy( pcNew->mKey.data, pKey ); - - if (UINT_MAX != iOutIndex) { - mProperties[iOutIndex] = pcNew; - return AI_SUCCESS; - } - - // resize the array ... double the storage allocated - if (mNumProperties == mNumAllocated) { - const unsigned int iOld = mNumAllocated; - mNumAllocated *= 2; - - aiMaterialProperty** ppTemp; - try { - ppTemp = new aiMaterialProperty*[mNumAllocated]; - } catch (std::bad_alloc&) { - delete pcNew; - return AI_OUTOFMEMORY; - } - - // just copy all items over; then replace the old array - memcpy (ppTemp,mProperties,iOld * sizeof(void*)); - - delete[] mProperties; - mProperties = ppTemp; - } - // push back ... - mProperties[mNumProperties++] = pcNew; - - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiMaterial::AddProperty (const aiString* pInput, - const char* pKey, - unsigned int type, - unsigned int index) -{ - ai_assert(sizeof(ai_uint32)==4); - return AddBinaryProperty(pInput, - static_cast<unsigned int>(pInput->length+1+4), - pKey, - type, - index, - aiPTI_String); -} - -// ------------------------------------------------------------------------------------------------ -uint32_t Assimp::ComputeMaterialHash(const aiMaterial* mat, bool includeMatName /*= false*/) -{ - uint32_t hash = 1503; // magic start value, chosen to be my birthday :-) - for ( unsigned int i = 0; i < mat->mNumProperties; ++i ) { - aiMaterialProperty* prop; - - // Exclude all properties whose first character is '?' from the hash - // See doc for aiMaterialProperty. - if ((prop = mat->mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?')) { - - hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash); - hash = SuperFastHash(prop->mData,prop->mDataLength,hash); - - // Combine the semantic and the index with the hash - hash = SuperFastHash((const char*)&prop->mSemantic,sizeof(unsigned int),hash); - hash = SuperFastHash((const char*)&prop->mIndex,sizeof(unsigned int),hash); - } - } - return hash; -} - -// ------------------------------------------------------------------------------------------------ -void aiMaterial::CopyPropertyList(aiMaterial* pcDest, - const aiMaterial* pcSrc - ) -{ - ai_assert(NULL != pcDest); - ai_assert(NULL != pcSrc); - - unsigned int iOldNum = pcDest->mNumProperties; - pcDest->mNumAllocated += pcSrc->mNumAllocated; - pcDest->mNumProperties += pcSrc->mNumProperties; - - aiMaterialProperty** pcOld = pcDest->mProperties; - pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated]; - - if (iOldNum && pcOld) { - for (unsigned int i = 0; i < iOldNum;++i) { - pcDest->mProperties[i] = pcOld[i]; - } - } - - if ( pcOld ) { - delete[] pcOld; - } - - for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i) { - aiMaterialProperty* propSrc = pcSrc->mProperties[i]; - - // search whether we have already a property with this name -> if yes, overwrite it - aiMaterialProperty* prop; - for ( unsigned int q = 0; q < iOldNum; ++q ) { - prop = pcDest->mProperties[q]; - if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic - && prop->mIndex == propSrc->mIndex) { - delete prop; - - // collapse the whole array ... - memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q); - i--; - pcDest->mNumProperties--; - } - } - - // Allocate the output property and copy the source property - prop = pcDest->mProperties[i] = new aiMaterialProperty(); - prop->mKey = propSrc->mKey; - prop->mDataLength = propSrc->mDataLength; - prop->mType = propSrc->mType; - prop->mSemantic = propSrc->mSemantic; - prop->mIndex = propSrc->mIndex; - - prop->mData = new char[propSrc->mDataLength]; - memcpy(prop->mData,propSrc->mData,prop->mDataLength); - } -} diff --git a/thirdparty/assimp/code/Material/MaterialSystem.h b/thirdparty/assimp/code/Material/MaterialSystem.h deleted file mode 100644 index 67d53578cb..0000000000 --- a/thirdparty/assimp/code/Material/MaterialSystem.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file MaterialSystem.h - * Now that #MaterialHelper is gone, this file only contains some - * internal material utility functions. - */ -#ifndef AI_MATERIALSYSTEM_H_INC -#define AI_MATERIALSYSTEM_H_INC - -#include <stdint.h> - -struct aiMaterial; - -namespace Assimp { - -// ------------------------------------------------------------------------------ -/** Computes a hash (hopefully unique) from all material properties - * The hash value reflects the current property state, so if you add any - * property and call this method again, the resulting hash value will be - * different. The hash is not persistent across different builds and platforms. - * - * @param includeMatName Set to 'true' to take all properties with - * '?' as initial character in their name into account. - * Currently #AI_MATKEY_NAME is the only example. - * @return 32 Bit jash value for the material - */ -uint32_t ComputeMaterialHash(const aiMaterial* mat, bool includeMatName = false); - - -} // ! namespace Assimp - -#endif //!! AI_MATERIALSYSTEM_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp deleted file mode 100644 index 75daeb6b59..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#include "ArmaturePopulate.h" - -#include <assimp/BaseImporter.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <iostream> - -namespace Assimp { - -/// The default class constructor. -ArmaturePopulate::ArmaturePopulate() : BaseProcess() -{} - -/// The class destructor. -ArmaturePopulate::~ArmaturePopulate() -{} - -bool ArmaturePopulate::IsActive(unsigned int pFlags) const { - return (pFlags & aiProcess_PopulateArmatureData) != 0; -} - -void ArmaturePopulate::SetupProperties(const Importer *pImp) { - // do nothing -} - -void ArmaturePopulate::Execute(aiScene *out) { - - // Now convert all bone positions to the correct mOffsetMatrix - std::vector<aiBone *> bones; - std::vector<aiNode *> nodes; - std::map<aiBone *, aiNode *> bone_stack; - BuildBoneList(out->mRootNode, out->mRootNode, out, bones); - BuildNodeList(out->mRootNode, nodes); - - BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes); - - ASSIMP_LOG_DEBUG_F("Bone stack size: ", bone_stack.size()); - - for (std::pair<aiBone *, aiNode *> kvp : bone_stack) { - aiBone *bone = kvp.first; - aiNode *bone_node = kvp.second; - ASSIMP_LOG_DEBUG_F("active node lookup: ", bone->mName.C_Str()); - // lcl transform grab - done in generate_nodes :) - - // bone->mOffsetMatrix = bone_node->mTransformation; - aiNode *armature = GetArmatureRoot(bone_node, bones); - - ai_assert(armature); - - // set up bone armature id - bone->mArmature = armature; - - // set this bone node to be referenced properly - ai_assert(bone_node); - bone->mNode = bone_node; - } -} - - -/* Reprocess all nodes to calculate bone transforms properly based on the REAL - * mOffsetMatrix not the local. */ -/* Before this would use mesh transforms which is wrong for bone transforms */ -/* Before this would work for simple character skeletons but not complex meshes - * with multiple origins */ -/* Source: sketch fab log cutter fbx */ -void ArmaturePopulate::BuildBoneList(aiNode *current_node, - const aiNode *root_node, - const aiScene *scene, - std::vector<aiBone *> &bones) { - ai_assert(scene); - for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) { - aiNode *child = current_node->mChildren[nodeId]; - ai_assert(child); - - // check for bones - for (unsigned int meshId = 0; meshId < child->mNumMeshes; ++meshId) { - ai_assert(child->mMeshes); - unsigned int mesh_index = child->mMeshes[meshId]; - aiMesh *mesh = scene->mMeshes[mesh_index]; - ai_assert(mesh); - - for (unsigned int boneId = 0; boneId < mesh->mNumBones; ++boneId) { - aiBone *bone = mesh->mBones[boneId]; - ai_assert(bone); - - // duplicate meshes exist with the same bones sometimes :) - // so this must be detected - if (std::find(bones.begin(), bones.end(), bone) == bones.end()) { - // add the element once - bones.push_back(bone); - } - } - - // find mesh and get bones - // then do recursive lookup for bones in root node hierarchy - } - - BuildBoneList(child, root_node, scene, bones); - } -} - -/* Prepare flat node list which can be used for non recursive lookups later */ -void ArmaturePopulate::BuildNodeList(const aiNode *current_node, - std::vector<aiNode *> &nodes) { - ai_assert(current_node); - - for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) { - aiNode *child = current_node->mChildren[nodeId]; - ai_assert(child); - - nodes.push_back(child); - - BuildNodeList(child, nodes); - } -} - -/* A bone stack allows us to have multiple armatures, with the same bone names - * A bone stack allows us also to retrieve bones true transform even with - * duplicate names :) - */ -void ArmaturePopulate::BuildBoneStack(aiNode *current_node, - const aiNode *root_node, - const aiScene *scene, - const std::vector<aiBone *> &bones, - std::map<aiBone *, aiNode *> &bone_stack, - std::vector<aiNode *> &node_stack) { - ai_assert(scene); - ai_assert(root_node); - ai_assert(!node_stack.empty()); - - for (aiBone *bone : bones) { - ai_assert(bone); - aiNode *node = GetNodeFromStack(bone->mName, node_stack); - if (node == nullptr) { - node_stack.clear(); - BuildNodeList(root_node, node_stack); - ASSIMP_LOG_DEBUG_F("Resetting bone stack: nullptr element ", bone->mName.C_Str()); - - node = GetNodeFromStack(bone->mName, node_stack); - - if (!node) { - ASSIMP_LOG_ERROR("serious import issue node for bone was not detected"); - continue; - } - } - - ASSIMP_LOG_DEBUG_F("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str()); - - bone_stack.insert(std::pair<aiBone *, aiNode *>(bone, node)); - } -} - - -/* Returns the armature root node */ -/* This is required to be detected for a bone initially, it will recurse up - * until it cannot find another bone and return the node No known failure - * points. (yet) - */ -aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node, - std::vector<aiBone *> &bone_list) { - while (bone_node) { - if (!IsBoneNode(bone_node->mName, bone_list)) { - ASSIMP_LOG_DEBUG_F("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str()); - return bone_node; - } - - bone_node = bone_node->mParent; - } - - ASSIMP_LOG_ERROR("GetArmatureRoot() can't find armature!"); - - return nullptr; -} - - - -/* Simple IsBoneNode check if this could be a bone */ -bool ArmaturePopulate::IsBoneNode(const aiString &bone_name, - std::vector<aiBone *> &bones) { - for (aiBone *bone : bones) { - if (bone->mName == bone_name) { - return true; - } - } - - return false; -} - -/* Pop this node by name from the stack if found */ -/* Used in multiple armature situations with duplicate node / bone names */ -/* Known flaw: cannot have nodes with bone names, will be fixed in later release - */ -/* (serious to be fixed) Known flaw: nodes which have more than one bone could - * be prematurely dropped from stack */ -aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name, - std::vector<aiNode *> &nodes) { - std::vector<aiNode *>::iterator iter; - aiNode *found = nullptr; - for (iter = nodes.begin(); iter < nodes.end(); ++iter) { - aiNode *element = *iter; - ai_assert(element); - // node valid and node name matches - if (element->mName == node_name) { - found = element; - break; - } - } - - if (found != nullptr) { - ASSIMP_LOG_INFO_F("Removed node from stack: ", found->mName.C_Str()); - // now pop the element from the node list - nodes.erase(iter); - - return found; - } - - // unique names can cause this problem - ASSIMP_LOG_ERROR("[Serious] GetNodeFromStack() can't find node from stack!"); - - return nullptr; -} - - - - -} // Namespace Assimp diff --git a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h deleted file mode 100644 index aa1ad7c80c..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#ifndef ARMATURE_POPULATE_H_ -#define ARMATURE_POPULATE_H_ - -#include "Common/BaseProcess.h" -#include <assimp/BaseImporter.h> -#include <vector> -#include <map> - - -struct aiNode; -struct aiBone; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** Armature Populate: This is a post process designed - * To save you time when importing models into your game engines - * This was originally designed only for fbx but will work with other formats - * it is intended to auto populate aiBone data with armature and the aiNode - * This is very useful when dealing with skinned meshes - * or when dealing with many different skeletons - * It's off by default but recommend that you try it and use it - * It should reduce down any glue code you have in your - * importers - * You can contact RevoluPowered <gordon@gordonite.tech> - * For more info about this -*/ -class ASSIMP_API ArmaturePopulate : public BaseProcess { -public: - /// The default class constructor. - ArmaturePopulate(); - - /// The class destructor. - virtual ~ArmaturePopulate(); - - /// Overwritten, @see BaseProcess - virtual bool IsActive( unsigned int pFlags ) const; - - /// Overwritten, @see BaseProcess - virtual void SetupProperties( const Importer* pImp ); - - /// Overwritten, @see BaseProcess - virtual void Execute( aiScene* pScene ); - - static aiNode *GetArmatureRoot(aiNode *bone_node, - std::vector<aiBone *> &bone_list); - - static bool IsBoneNode(const aiString &bone_name, - std::vector<aiBone *> &bones); - - static aiNode *GetNodeFromStack(const aiString &node_name, - std::vector<aiNode *> &nodes); - - static void BuildNodeList(const aiNode *current_node, - std::vector<aiNode *> &nodes); - - static void BuildBoneList(aiNode *current_node, const aiNode *root_node, - const aiScene *scene, - std::vector<aiBone *> &bones); - - static void BuildBoneStack(aiNode *current_node, const aiNode *root_node, - const aiScene *scene, - const std::vector<aiBone *> &bones, - std::map<aiBone *, aiNode *> &bone_stack, - std::vector<aiNode *> &node_stack); -}; - -} // Namespace Assimp - - -#endif // SCALE_PROCESS_H_
\ No newline at end of file diff --git a/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp deleted file mode 100644 index a3f7dd2557..0000000000 --- a/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to calculate - * tangents and bitangents for all imported meshes - */ - -// internal headers -#include "CalcTangentsProcess.h" -#include "ProcessHelper.h" -#include <assimp/TinyFormatter.h> -#include <assimp/qnan.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -CalcTangentsProcess::CalcTangentsProcess() -: configMaxAngle( AI_DEG_TO_RAD(45.f) ) -, configSourceUV( 0 ) { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -CalcTangentsProcess::~CalcTangentsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool CalcTangentsProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_CalcTangentSpace) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void CalcTangentsProcess::SetupProperties(const Importer* pImp) -{ - ai_assert( NULL != pImp ); - - // get the current value of the property - configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f); - configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f); - configMaxAngle = AI_DEG_TO_RAD(configMaxAngle); - - configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void CalcTangentsProcess::Execute( aiScene* pScene) -{ - ai_assert( NULL != pScene ); - - ASSIMP_LOG_DEBUG("CalcTangentsProcess begin"); - - bool bHas = false; - for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) { - if(ProcessMesh( pScene->mMeshes[a],a))bHas = true; - } - - if ( bHas ) { - ASSIMP_LOG_INFO("CalcTangentsProcess finished. Tangents have been calculated"); - } else { - ASSIMP_LOG_DEBUG("CalcTangentsProcess finished"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Calculates tangents and bi-tangents for the given mesh -bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) -{ - // we assume that the mesh is still in the verbose vertex format where each face has its own set - // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to - // assert() it here. - // assert( must be verbose, dammit); - - if (pMesh->mTangents) // this implies that mBitangents is also there - return false; - - // If the mesh consists of lines and/or points but not of - // triangles or higher-order polygons the normal vectors - // are undefined. - if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) - { - ASSIMP_LOG_INFO("Tangents are undefined for line and point meshes"); - return false; - } - - // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement - if( pMesh->mNormals == NULL) - { - ASSIMP_LOG_ERROR("Failed to compute tangents; need normals"); - return false; - } - if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] ) - { - ASSIMP_LOG_ERROR((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV)); - return false; - } - - const float angleEpsilon = 0.9999f; - - std::vector<bool> vertexDone( pMesh->mNumVertices, false); - const float qnan = get_qnan(); - - // create space for the tangents and bitangents - pMesh->mTangents = new aiVector3D[pMesh->mNumVertices]; - pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices]; - - const aiVector3D* meshPos = pMesh->mVertices; - const aiVector3D* meshNorm = pMesh->mNormals; - const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV]; - aiVector3D* meshTang = pMesh->mTangents; - aiVector3D* meshBitang = pMesh->mBitangents; - - // calculate the tangent and bitangent for every face - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) - { - const aiFace& face = pMesh->mFaces[a]; - if (face.mNumIndices < 3) - { - // There are less than three indices, thus the tangent vector - // is not defined. We are finished with these vertices now, - // their tangent vectors are set to qnan. - for (unsigned int i = 0; i < face.mNumIndices;++i) - { - unsigned int idx = face.mIndices[i]; - vertexDone [idx] = true; - meshTang [idx] = aiVector3D(qnan); - meshBitang [idx] = aiVector3D(qnan); - } - - continue; - } - - // triangle or polygon... we always use only the first three indices. A polygon - // is supposed to be planar anyways.... - // FIXME: (thom) create correct calculation for multi-vertex polygons maybe? - const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2]; - - // position differences p1->p2 and p1->p3 - aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0]; - - // texture offset p1->p2 and p1->p3 - float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y; - float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y; - float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f; - // when t1, t2, t3 in same position in UV space, just use default UV direction. - if ( sx * ty == sy * tx ) { - sx = 0.0; sy = 1.0; - tx = 1.0; ty = 0.0; - } - - // tangent points in the direction where to positive X axis of the texture coord's would point in model space - // bitangent's points along the positive Y axis of the texture coord's, respectively - aiVector3D tangent, bitangent; - tangent.x = (w.x * sy - v.x * ty) * dirCorrection; - tangent.y = (w.y * sy - v.y * ty) * dirCorrection; - tangent.z = (w.z * sy - v.z * ty) * dirCorrection; - bitangent.x = (w.x * sx - v.x * tx) * dirCorrection; - bitangent.y = (w.y * sx - v.y * tx) * dirCorrection; - bitangent.z = (w.z * sx - v.z * tx) * dirCorrection; - - // store for every vertex of that face - for( unsigned int b = 0; b < face.mNumIndices; ++b ) { - unsigned int p = face.mIndices[b]; - - // project tangent and bitangent into the plane formed by the vertex' normal - aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]); - aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); - localTangent.NormalizeSafe(); localBitangent.NormalizeSafe(); - - // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN. - bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z); - bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z); - if (invalid_tangent != invalid_bitangent) { - if (invalid_tangent) { - localTangent = meshNorm[p] ^ localBitangent; - localTangent.NormalizeSafe(); - } else { - localBitangent = localTangent ^ meshNorm[p]; - localBitangent.NormalizeSafe(); - } - } - - // and write it into the mesh. - meshTang[ p ] = localTangent; - meshBitang[ p ] = localBitangent; - } - } - - - // create a helper to quickly find locally close vertices among the vertex array - // FIX: check whether we can reuse the SpatialSort of a previous step - SpatialSort* vertexFinder = NULL; - SpatialSort _vertexFinder; - float posEpsilon; - if (shared) - { - std::vector<std::pair<SpatialSort,float> >* avf; - shared->GetProperty(AI_SPP_SPATIAL_SORT,avf); - if (avf) - { - std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex); - vertexFinder = &blubb.first; - posEpsilon = blubb.second;; - } - } - if (!vertexFinder) - { - _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D)); - vertexFinder = &_vertexFinder; - posEpsilon = ComputePositionEpsilon(pMesh); - } - std::vector<unsigned int> verticesFound; - - const float fLimit = std::cos(configMaxAngle); - std::vector<unsigned int> closeVertices; - - // in the second pass we now smooth out all tangents and bitangents at the same local position - // if they are not too far off. - for( unsigned int a = 0; a < pMesh->mNumVertices; a++) - { - if( vertexDone[a]) - continue; - - const aiVector3D& origPos = pMesh->mVertices[a]; - const aiVector3D& origNorm = pMesh->mNormals[a]; - const aiVector3D& origTang = pMesh->mTangents[a]; - const aiVector3D& origBitang = pMesh->mBitangents[a]; - closeVertices.resize( 0 ); - - // find all vertices close to that position - vertexFinder->FindPositions( origPos, posEpsilon, verticesFound); - - closeVertices.reserve (verticesFound.size()+5); - closeVertices.push_back( a); - - // look among them for other vertices sharing the same normal and a close-enough tangent/bitangent - for( unsigned int b = 0; b < verticesFound.size(); b++) - { - unsigned int idx = verticesFound[b]; - if( vertexDone[idx]) - continue; - if( meshNorm[idx] * origNorm < angleEpsilon) - continue; - if( meshTang[idx] * origTang < fLimit) - continue; - if( meshBitang[idx] * origBitang < fLimit) - continue; - - // it's similar enough -> add it to the smoothing group - closeVertices.push_back( idx); - vertexDone[idx] = true; - } - - // smooth the tangents and bitangents of all vertices that were found to be close enough - aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0); - for( unsigned int b = 0; b < closeVertices.size(); ++b) - { - smoothTangent += meshTang[ closeVertices[b] ]; - smoothBitangent += meshBitang[ closeVertices[b] ]; - } - smoothTangent.Normalize(); - smoothBitangent.Normalize(); - - // and write it back into all affected tangents - for( unsigned int b = 0; b < closeVertices.size(); ++b) - { - meshTang[ closeVertices[b] ] = smoothTangent; - meshBitang[ closeVertices[b] ] = smoothBitangent; - } - } - return true; -} diff --git a/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h deleted file mode 100644 index 3568a624f8..0000000000 --- a/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - - -/** @file Defines a post processing step to calculate tangents and - bi-tangents on all imported meshes.*/ -#ifndef AI_CALCTANGENTSPROCESS_H_INC -#define AI_CALCTANGENTSPROCESS_H_INC - -#include "Common/BaseProcess.h" - -struct aiMesh; - -namespace Assimp -{ - -// --------------------------------------------------------------------------- -/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex - * of all meshes. It is expected to be run before the JoinVerticesProcess runs - * because the joining of vertices also considers tangents and bitangents for - * uniqueness. - */ -class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess -{ -public: - - CalcTangentsProcess(); - ~CalcTangentsProcess(); - -public: - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. - * A bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - void SetupProperties(const Importer* pImp); - - - // setter for configMaxAngle - inline void SetMaxSmoothAngle(float f) - { - configMaxAngle =f; - } - -protected: - - // ------------------------------------------------------------------- - /** Calculates tangents and bitangents for a specific mesh. - * @param pMesh The mesh to process. - * @param meshIndex Index of the mesh - */ - bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex); - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - -private: - - /** Configuration option: maximum smoothing angle, in radians*/ - float configMaxAngle; - unsigned int configSourceUV; -}; - -} // end of namespace Assimp - -#endif // AI_CALCTANGENTSPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp deleted file mode 100644 index df4d44337d..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file GenUVCoords step */ - - -#include "ComputeUVMappingProcess.h" -#include "ProcessHelper.h" -#include <assimp/Exceptional.h> - -using namespace Assimp; - -namespace { - - const static aiVector3D base_axis_y(0.0,1.0,0.0); - const static aiVector3D base_axis_x(1.0,0.0,0.0); - const static aiVector3D base_axis_z(0.0,0.0,1.0); - const static ai_real angle_epsilon = ai_real( 0.95 ); -} - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -ComputeUVMappingProcess::ComputeUVMappingProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -ComputeUVMappingProcess::~ComputeUVMappingProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_GenUVCoords) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Check whether a ray intersects a plane and find the intersection point -inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, - const aiVector3D& planeNormal, aiVector3D& pos) -{ - const ai_real b = planeNormal * (planePos - ray.pos); - ai_real h = ray.dir * planeNormal; - if ((h < 10e-5 && h > -10e-5) || (h = b/h) < 0) - return false; - - pos = ray.pos + (ray.dir * h); - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Find the first empty UV channel in a mesh -inline unsigned int FindEmptyUVChannel (aiMesh* mesh) -{ - for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m) - if (!mesh->mTextureCoords[m])return m; - - ASSIMP_LOG_ERROR("Unable to compute UV coordinates, no free UV slot found"); - return UINT_MAX; -} - -// ------------------------------------------------------------------------------------------------ -// Try to remove UV seams -void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) -{ - // TODO: just a very rough algorithm. I think it could be done - // much easier, but I don't know how and am currently too tired to - // to think about a better solution. - - const static ai_real LOWER_LIMIT = ai_real( 0.1 ); - const static ai_real UPPER_LIMIT = ai_real( 0.9 ); - - const static ai_real LOWER_EPSILON = ai_real( 10e-3 ); - const static ai_real UPPER_EPSILON = ai_real( 1.0-10e-3 ); - - for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx) - { - const aiFace& face = mesh->mFaces[fidx]; - if (face.mNumIndices < 3) continue; // triangles and polygons only, please - - unsigned int small = face.mNumIndices, large = small; - bool zero = false, one = false, round_to_zero = false; - - // Check whether this face lies on a UV seam. We can just guess, - // but the assumption that a face with at least one very small - // on the one side and one very large U coord on the other side - // lies on a UV seam should work for most cases. - for (unsigned int n = 0; n < face.mNumIndices;++n) - { - if (out[face.mIndices[n]].x < LOWER_LIMIT) - { - small = n; - - // If we have a U value very close to 0 we can't - // round the others to 0, too. - if (out[face.mIndices[n]].x <= LOWER_EPSILON) - zero = true; - else round_to_zero = true; - } - if (out[face.mIndices[n]].x > UPPER_LIMIT) - { - large = n; - - // If we have a U value very close to 1 we can't - // round the others to 1, too. - if (out[face.mIndices[n]].x >= UPPER_EPSILON) - one = true; - } - } - if (small != face.mNumIndices && large != face.mNumIndices) - { - for (unsigned int n = 0; n < face.mNumIndices;++n) - { - // If the u value is over the upper limit and no other u - // value of that face is 0, round it to 0 - if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero) - out[face.mIndices[n]].x = 0.0; - - // If the u value is below the lower limit and no other u - // value of that face is 1, round it to 1 - else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one) - out[face.mIndices[n]].x = 1.0; - - // The face contains both 0 and 1 as UV coords. This can occur - // for faces which have an edge that lies directly on the seam. - // Due to numerical inaccuracies one U coord becomes 0, the - // other 1. But we do still have a third UV coord to determine - // to which side we must round to. - else if (one && zero) - { - if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON) - out[face.mIndices[n]].x = 0.0; - else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON) - out[face.mIndices[n]].x = 1.0; - } - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) -{ - aiVector3D center, min, max; - FindMeshCenter(mesh, center, min, max); - - // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... - // currently the mapping axis will always be one of x,y,z, except if the - // PretransformVertices step is used (it transforms the meshes into worldspace, - // thus changing the mapping axis) - if (axis * base_axis_x >= angle_epsilon) { - - // For each point get a normalized projection vector in the sphere, - // get its longitude and latitude and map them to their respective - // UV axes. Problems occur around the poles ... unsolvable. - // - // The spherical coordinate system looks like this: - // x = cos(lon)*cos(lat) - // y = sin(lon)*cos(lat) - // z = sin(lat) - // - // Thus we can derive: - // lat = arcsin (z) - // lon = arctan (y/x) - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); - out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, - (std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); - } - } - else if (axis * base_axis_y >= angle_epsilon) { - // ... just the same again - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); - out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, - (std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); - } - } - else if (axis * base_axis_z >= angle_epsilon) { - // ... just the same again - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); - out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, - (std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); - } - } - // slower code path in case the mapping axis is not one of the coordinate system axes - else { - aiMatrix4x4 mTrafo; - aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); - - // again the same, except we're applying a transformation now - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize(); - out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, - (std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); - } - } - - - // Now find and remove UV seams. A seam occurs if a face has a tcoord - // close to zero on the one side, and a tcoord close to one on the - // other side. - RemoveUVSeams(mesh,out); -} - -// ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) -{ - aiVector3D center, min, max; - - // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... - // currently the mapping axis will always be one of x,y,z, except if the - // PretransformVertices step is used (it transforms the meshes into worldspace, - // thus changing the mapping axis) - if (axis * base_axis_x >= angle_epsilon) { - FindMeshCenter(mesh, center, min, max); - const ai_real diff = max.x - min.x; - - // If the main axis is 'z', the z coordinate of a point 'p' is mapped - // directly to the texture V axis. The other axis is derived from - // the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where - // 'c' is the center point of the mesh. - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D& pos = mesh->mVertices[pnt]; - aiVector3D& uv = out[pnt]; - - uv.y = (pos.x - min.x) / diff; - uv.x = (std::atan2( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; - } - } - else if (axis * base_axis_y >= angle_epsilon) { - FindMeshCenter(mesh, center, min, max); - const ai_real diff = max.y - min.y; - - // just the same ... - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D& pos = mesh->mVertices[pnt]; - aiVector3D& uv = out[pnt]; - - uv.y = (pos.y - min.y) / diff; - uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; - } - } - else if (axis * base_axis_z >= angle_epsilon) { - FindMeshCenter(mesh, center, min, max); - const ai_real diff = max.z - min.z; - - // just the same ... - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D& pos = mesh->mVertices[pnt]; - aiVector3D& uv = out[pnt]; - - uv.y = (pos.z - min.z) / diff; - uv.x = (std::atan2( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; - } - } - // slower code path in case the mapping axis is not one of the coordinate system axes - else { - aiMatrix4x4 mTrafo; - aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); - FindMeshCenterTransformed(mesh, center, min, max,mTrafo); - const ai_real diff = max.y - min.y; - - // again the same, except we're applying a transformation now - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){ - const aiVector3D pos = mTrafo* mesh->mVertices[pnt]; - aiVector3D& uv = out[pnt]; - - uv.y = (pos.y - min.y) / diff; - uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; - } - } - - // Now find and remove UV seams. A seam occurs if a face has a tcoord - // close to zero on the one side, and a tcoord close to one on the - // other side. - RemoveUVSeams(mesh,out); -} - -// ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) -{ - ai_real diffu,diffv; - aiVector3D center, min, max; - - // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... - // currently the mapping axis will always be one of x,y,z, except if the - // PretransformVertices step is used (it transforms the meshes into worldspace, - // thus changing the mapping axis) - if (axis * base_axis_x >= angle_epsilon) { - FindMeshCenter(mesh, center, min, max); - diffu = max.z - min.z; - diffv = max.y - min.y; - - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D& pos = mesh->mVertices[pnt]; - out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.0); - } - } - else if (axis * base_axis_y >= angle_epsilon) { - FindMeshCenter(mesh, center, min, max); - diffu = max.x - min.x; - diffv = max.z - min.z; - - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D& pos = mesh->mVertices[pnt]; - out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.0); - } - } - else if (axis * base_axis_z >= angle_epsilon) { - FindMeshCenter(mesh, center, min, max); - diffu = max.x - min.x; - diffv = max.y - min.y; - - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D& pos = mesh->mVertices[pnt]; - out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0); - } - } - // slower code path in case the mapping axis is not one of the coordinate system axes - else - { - aiMatrix4x4 mTrafo; - aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); - FindMeshCenterTransformed(mesh, center, min, max,mTrafo); - diffu = max.x - min.x; - diffv = max.z - min.z; - - // again the same, except we're applying a transformation now - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - const aiVector3D pos = mTrafo * mesh->mVertices[pnt]; - out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.0); - } - } - - // shouldn't be necessary to remove UV seams ... -} - -// ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* ) -{ - ASSIMP_LOG_ERROR("Mapping type currently not implemented"); -} - -// ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin"); - char buffer[1024]; - - if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) - throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); - - std::list<MappingInfo> mappingStack; - - /* Iterate through all materials and search for non-UV mapped textures - */ - for (unsigned int i = 0; i < pScene->mNumMaterials;++i) - { - mappingStack.clear(); - aiMaterial* mat = pScene->mMaterials[i]; - for (unsigned int a = 0; a < mat->mNumProperties;++a) - { - aiMaterialProperty* prop = mat->mProperties[a]; - if (!::strcmp( prop->mKey.data, "$tex.mapping")) - { - aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData); - if (aiTextureMapping_UV != mapping) - { - if (!DefaultLogger::isNullLogger()) - { - ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s", - TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex, - MappingTypeToString(mapping)); - - ASSIMP_LOG_INFO(buffer); - } - - if (aiTextureMapping_OTHER == mapping) - continue; - - MappingInfo info (mapping); - - // Get further properties - currently only the major axis - for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2) - { - aiMaterialProperty* prop2 = mat->mProperties[a2]; - if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) - continue; - - if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) { - info.axis = *((aiVector3D*)prop2->mData); - break; - } - } - - unsigned int idx( 99999999 ); - - // Check whether we have this mapping mode already - std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info); - if (mappingStack.end() != it) - { - idx = (*it).uv; - } - else - { - /* We have found a non-UV mapped texture. Now - * we need to find all meshes using this material - * that we can compute UV channels for them. - */ - for (unsigned int m = 0; m < pScene->mNumMeshes;++m) - { - aiMesh* mesh = pScene->mMeshes[m]; - unsigned int outIdx = 0; - if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX || - !mesh->mNumVertices) - { - continue; - } - - // Allocate output storage - aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices]; - - switch (mapping) - { - case aiTextureMapping_SPHERE: - ComputeSphereMapping(mesh,info.axis,p); - break; - case aiTextureMapping_CYLINDER: - ComputeCylinderMapping(mesh,info.axis,p); - break; - case aiTextureMapping_PLANE: - ComputePlaneMapping(mesh,info.axis,p); - break; - case aiTextureMapping_BOX: - ComputeBoxMapping(mesh,p); - break; - default: - ai_assert(false); - } - if (m && idx != outIdx) - { - ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to " - "this material have equal numbers of UV channels. The UV index stored in " - "the material structure does therefore not apply for all meshes. "); - } - idx = outIdx; - } - info.uv = idx; - mappingStack.push_back(info); - } - - // Update the material property list - mapping = aiTextureMapping_UV; - ((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex)); - } - } - } - } - ASSIMP_LOG_DEBUG("GenUVCoordsProcess finished"); -} diff --git a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h deleted file mode 100644 index a6d36e06ea..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h +++ /dev/null @@ -1,149 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to compute UV coordinates - from abstract mappings, such as box or spherical*/ -#ifndef AI_COMPUTEUVMAPPING_H_INC -#define AI_COMPUTEUVMAPPING_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> -#include <assimp/material.h> -#include <assimp/types.h> - -class ComputeUVMappingTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** ComputeUVMappingProcess - converts special mappings, such as spherical, - * cylindrical or boxed to proper UV coordinates for rendering. -*/ -class ComputeUVMappingProcess : public BaseProcess -{ -public: - ComputeUVMappingProcess(); - ~ComputeUVMappingProcess(); - -public: - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - -protected: - - // ------------------------------------------------------------------- - /** Computes spherical UV coordinates for a mesh - * - * @param mesh Mesh to be processed - * @param axis Main axis - * @param out Receives output UV coordinates - */ - void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, - aiVector3D* out); - - // ------------------------------------------------------------------- - /** Computes cylindrical UV coordinates for a mesh - * - * @param mesh Mesh to be processed - * @param axis Main axis - * @param out Receives output UV coordinates - */ - void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, - aiVector3D* out); - - // ------------------------------------------------------------------- - /** Computes planar UV coordinates for a mesh - * - * @param mesh Mesh to be processed - * @param axis Main axis - * @param out Receives output UV coordinates - */ - void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, - aiVector3D* out); - - // ------------------------------------------------------------------- - /** Computes cubic UV coordinates for a mesh - * - * @param mesh Mesh to be processed - * @param out Receives output UV coordinates - */ - void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out); - -private: - - // temporary structure to describe a mapping - struct MappingInfo - { - explicit MappingInfo(aiTextureMapping _type) - : type (_type) - , axis (0.f,1.f,0.f) - , uv (0u) - {} - - aiTextureMapping type; - aiVector3D axis; - unsigned int uv; - - bool operator== (const MappingInfo& other) - { - return type == other.type && axis == other.axis; - } - }; -}; - -} // end of namespace Assimp - -#endif // AI_COMPUTEUVMAPPING_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp deleted file mode 100644 index b7cd4f0bc6..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file MakeLeftHandedProcess.cpp - * @brief Implementation of the post processing step to convert all - * imported data to a left-handed coordinate system. - * - * Face order & UV flip are also implemented here, for the sake of a - * better location. - */ - - -#include "ConvertToLHProcess.h" -#include <assimp/scene.h> -#include <assimp/postprocess.h> -#include <assimp/DefaultLogger.hpp> - -using namespace Assimp; - -#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS - -namespace { - -template <typename aiMeshType> -void flipUVs(aiMeshType* pMesh) { - if (pMesh == nullptr) { return; } - // mirror texture y coordinate - for (unsigned int tcIdx = 0; tcIdx < AI_MAX_NUMBER_OF_TEXTURECOORDS; tcIdx++) { - if (!pMesh->HasTextureCoords(tcIdx)) { - break; - } - - for (unsigned int vIdx = 0; vIdx < pMesh->mNumVertices; vIdx++) { - pMesh->mTextureCoords[tcIdx][vIdx].y = 1.0f - pMesh->mTextureCoords[tcIdx][vIdx].y; - } - } -} - -} // namespace - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -MakeLeftHandedProcess::MakeLeftHandedProcess() -: BaseProcess() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -MakeLeftHandedProcess::~MakeLeftHandedProcess() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const -{ - return 0 != (pFlags & aiProcess_MakeLeftHanded); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void MakeLeftHandedProcess::Execute( aiScene* pScene) -{ - // Check for an existent root node to proceed - ai_assert(pScene->mRootNode != NULL); - ASSIMP_LOG_DEBUG("MakeLeftHandedProcess begin"); - - // recursively convert all the nodes - ProcessNode( pScene->mRootNode, aiMatrix4x4()); - - // process the meshes accordingly - for ( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) { - ProcessMesh( pScene->mMeshes[ a ] ); - } - - // process the materials accordingly - for ( unsigned int a = 0; a < pScene->mNumMaterials; ++a ) { - ProcessMaterial( pScene->mMaterials[ a ] ); - } - - // transform all animation channels as well - for( unsigned int a = 0; a < pScene->mNumAnimations; a++) - { - aiAnimation* anim = pScene->mAnimations[a]; - for( unsigned int b = 0; b < anim->mNumChannels; b++) - { - aiNodeAnim* nodeAnim = anim->mChannels[b]; - ProcessAnimation( nodeAnim); - } - } - ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished"); -} - -// ------------------------------------------------------------------------------------------------ -// Recursively converts a node, all of its children and all of its meshes -void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation) -{ - // mirror all base vectors at the local Z axis - pNode->mTransformation.c1 = -pNode->mTransformation.c1; - pNode->mTransformation.c2 = -pNode->mTransformation.c2; - pNode->mTransformation.c3 = -pNode->mTransformation.c3; - pNode->mTransformation.c4 = -pNode->mTransformation.c4; - - // now invert the Z axis again to keep the matrix determinant positive. - // The local meshes will be inverted accordingly so that the result should look just fine again. - pNode->mTransformation.a3 = -pNode->mTransformation.a3; - pNode->mTransformation.b3 = -pNode->mTransformation.b3; - pNode->mTransformation.c3 = -pNode->mTransformation.c3; - pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways... - - // continue for all children - for( size_t a = 0; a < pNode->mNumChildren; ++a ) { - ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Converts a single mesh to left handed coordinates. -void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) { - if ( nullptr == pMesh ) { - ASSIMP_LOG_ERROR( "Nullptr to mesh found." ); - return; - } - // mirror positions, normals and stuff along the Z axis - for( size_t a = 0; a < pMesh->mNumVertices; ++a) - { - pMesh->mVertices[a].z *= -1.0f; - if (pMesh->HasNormals()) { - pMesh->mNormals[a].z *= -1.0f; - } - if( pMesh->HasTangentsAndBitangents()) - { - pMesh->mTangents[a].z *= -1.0f; - pMesh->mBitangents[a].z *= -1.0f; - } - } - - // mirror anim meshes positions, normals and stuff along the Z axis - for (size_t m = 0; m < pMesh->mNumAnimMeshes; ++m) - { - for (size_t a = 0; a < pMesh->mAnimMeshes[m]->mNumVertices; ++a) - { - pMesh->mAnimMeshes[m]->mVertices[a].z *= -1.0f; - if (pMesh->mAnimMeshes[m]->HasNormals()) { - pMesh->mAnimMeshes[m]->mNormals[a].z *= -1.0f; - } - if (pMesh->mAnimMeshes[m]->HasTangentsAndBitangents()) - { - pMesh->mAnimMeshes[m]->mTangents[a].z *= -1.0f; - pMesh->mAnimMeshes[m]->mBitangents[a].z *= -1.0f; - } - } - } - - // mirror offset matrices of all bones - for( size_t a = 0; a < pMesh->mNumBones; ++a) - { - aiBone* bone = pMesh->mBones[a]; - bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3; - bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3; - bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3; - bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1; - bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2; - bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4; - } - - // mirror bitangents as well as they're derived from the texture coords - if( pMesh->HasTangentsAndBitangents()) - { - for( unsigned int a = 0; a < pMesh->mNumVertices; a++) - pMesh->mBitangents[a] *= -1.0f; - } -} - -// ------------------------------------------------------------------------------------------------ -// Converts a single material to left handed coordinates. -void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) { - if ( nullptr == _mat ) { - ASSIMP_LOG_ERROR( "Nullptr to aiMaterial found." ); - return; - } - - aiMaterial* mat = (aiMaterial*)_mat; - for (unsigned int a = 0; a < mat->mNumProperties;++a) { - aiMaterialProperty* prop = mat->mProperties[a]; - - // Mapping axis for UV mappings? - if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) { - ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */ - aiVector3D* pff = (aiVector3D*)prop->mData; - pff->z *= -1.f; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Converts the given animation to LH coordinates. -void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim) -{ - // position keys - for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++) - pAnim->mPositionKeys[a].mValue.z *= -1.0f; - - // rotation keys - for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) - { - /* That's the safe version, but the float errors add up. So we try the short version instead - aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix(); - rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3; - rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2; - aiQuaternion rotquat( rotmat); - pAnim->mRotationKeys[a].mValue = rotquat; - */ - pAnim->mRotationKeys[a].mValue.x *= -1.0f; - pAnim->mRotationKeys[a].mValue.y *= -1.0f; - } -} - -#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS -#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS -// # FlipUVsProcess - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -FlipUVsProcess::FlipUVsProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FlipUVsProcess::~FlipUVsProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool FlipUVsProcess::IsActive( unsigned int pFlags) const -{ - return 0 != (pFlags & aiProcess_FlipUVs); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void FlipUVsProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("FlipUVsProcess begin"); - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) - ProcessMesh(pScene->mMeshes[i]); - - for (unsigned int i = 0; i < pScene->mNumMaterials;++i) - ProcessMaterial(pScene->mMaterials[i]); - ASSIMP_LOG_DEBUG("FlipUVsProcess finished"); -} - -// ------------------------------------------------------------------------------------------------ -// Converts a single material -void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat) -{ - aiMaterial* mat = (aiMaterial*)_mat; - for (unsigned int a = 0; a < mat->mNumProperties;++a) { - aiMaterialProperty* prop = mat->mProperties[a]; - if( !prop ) { - ASSIMP_LOG_DEBUG( "Property is null" ); - continue; - } - - // UV transformation key? - if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) { - ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */ - aiUVTransform* uv = (aiUVTransform*)prop->mData; - - // just flip it, that's everything - uv->mTranslation.y *= -1.f; - uv->mRotation *= -1.f; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Converts a single mesh -void FlipUVsProcess::ProcessMesh( aiMesh* pMesh) -{ - flipUVs(pMesh); - for (unsigned int idx = 0; idx < pMesh->mNumAnimMeshes; idx++) { - flipUVs(pMesh->mAnimMeshes[idx]); - } -} - -#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS -#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS -// # FlipWindingOrderProcess - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -FlipWindingOrderProcess::FlipWindingOrderProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FlipWindingOrderProcess::~FlipWindingOrderProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const -{ - return 0 != (pFlags & aiProcess_FlipWindingOrder); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void FlipWindingOrderProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("FlipWindingOrderProcess begin"); - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) - ProcessMesh(pScene->mMeshes[i]); - ASSIMP_LOG_DEBUG("FlipWindingOrderProcess finished"); -} - -// ------------------------------------------------------------------------------------------------ -// Converts a single mesh -void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh) -{ - // invert the order of all faces in this mesh - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) - { - aiFace& face = pMesh->mFaces[a]; - for (unsigned int b = 0; b < face.mNumIndices / 2; b++) { - std::swap(face.mIndices[b], face.mIndices[face.mNumIndices - 1 - b]); - } - } - - // invert the order of all components in this mesh anim meshes - for (unsigned int m = 0; m < pMesh->mNumAnimMeshes; m++) { - aiAnimMesh* animMesh = pMesh->mAnimMeshes[m]; - unsigned int numVertices = animMesh->mNumVertices; - if (animMesh->HasPositions()) { - for (unsigned int a = 0; a < numVertices; a++) - { - std::swap(animMesh->mVertices[a], animMesh->mVertices[numVertices - 1 - a]); - } - } - if (animMesh->HasNormals()) { - for (unsigned int a = 0; a < numVertices; a++) - { - std::swap(animMesh->mNormals[a], animMesh->mNormals[numVertices - 1 - a]); - } - } - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) { - if (animMesh->HasTextureCoords(i)) { - for (unsigned int a = 0; a < numVertices; a++) - { - std::swap(animMesh->mTextureCoords[i][a], animMesh->mTextureCoords[i][numVertices - 1 - a]); - } - } - } - if (animMesh->HasTangentsAndBitangents()) { - for (unsigned int a = 0; a < numVertices; a++) - { - std::swap(animMesh->mTangents[a], animMesh->mTangents[numVertices - 1 - a]); - std::swap(animMesh->mBitangents[a], animMesh->mBitangents[numVertices - 1 - a]); - } - } - for (unsigned int v = 0; v < AI_MAX_NUMBER_OF_COLOR_SETS; v++) { - if (animMesh->HasVertexColors(v)) { - for (unsigned int a = 0; a < numVertices; a++) - { - std::swap(animMesh->mColors[v][a], animMesh->mColors[v][numVertices - 1 - a]); - } - } - } - } -} - -#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h deleted file mode 100644 index f32b91fc39..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file MakeLeftHandedProcess.h - * @brief Defines a bunch of post-processing steps to handle - * coordinate system conversions. - * - * - LH to RH - * - UV origin upper-left to lower-left - * - face order cw to ccw - */ -#ifndef AI_CONVERTTOLHPROCESS_H_INC -#define AI_CONVERTTOLHPROCESS_H_INC - -#include <assimp/types.h> - -#include "Common/BaseProcess.h" - -struct aiMesh; -struct aiNodeAnim; -struct aiNode; -struct aiMaterial; - -namespace Assimp { - -// ----------------------------------------------------------------------------------- -/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed - * coordinate system. - * - * This implies a mirroring of the Z axis of the coordinate system. But to keep - * transformation matrices free from reflections we shift the reflection to other - * places. We mirror the meshes and adapt the rotations. - * - * @note RH-LH and LH-RH is the same, so this class can be used for both - */ -class MakeLeftHandedProcess : public BaseProcess -{ - - -public: - MakeLeftHandedProcess(); - ~MakeLeftHandedProcess(); - - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - -protected: - - // ------------------------------------------------------------------- - /** Recursively converts a node and all of its children - */ - void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation); - - // ------------------------------------------------------------------- - /** Converts a single mesh to left handed coordinates. - * This means that positions, normals and tangents are mirrored at - * the local Z axis and the order of all faces are inverted. - * @param pMesh The mesh to convert. - */ - void ProcessMesh( aiMesh* pMesh); - - // ------------------------------------------------------------------- - /** Converts a single material to left-handed coordinates - * @param pMat Material to convert - */ - void ProcessMaterial( aiMaterial* pMat); - - // ------------------------------------------------------------------- - /** Converts the given animation to LH coordinates. - * The rotation and translation keys are transformed, the scale keys - * work in local space and can therefore be left untouched. - * @param pAnim The bone animation to transform - */ - void ProcessAnimation( aiNodeAnim* pAnim); -}; - - -// --------------------------------------------------------------------------- -/** Postprocessing step to flip the face order of the imported data - */ -class FlipWindingOrderProcess : public BaseProcess -{ - friend class Importer; - -public: - /** Constructor to be privately used by Importer */ - FlipWindingOrderProcess(); - - /** Destructor, private as well */ - ~FlipWindingOrderProcess(); - - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - -protected: - void ProcessMesh( aiMesh* pMesh); -}; - -// --------------------------------------------------------------------------- -/** Postprocessing step to flip the UV coordinate system of the import data - */ -class FlipUVsProcess : public BaseProcess -{ - friend class Importer; - -public: - /** Constructor to be privately used by Importer */ - FlipUVsProcess(); - - /** Destructor, private as well */ - ~FlipUVsProcess(); - - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - -protected: - void ProcessMesh( aiMesh* pMesh); - void ProcessMaterial( aiMaterial* mat); -}; - -} // end of namespace Assimp - -#endif // AI_CONVERTTOLHPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp b/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp deleted file mode 100644 index 83b8336bc9..0000000000 --- a/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp +++ /dev/null @@ -1,465 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/// @file DeboneProcess.cpp -/** Implementation of the DeboneProcess post processing step */ - - - -// internal headers of the post-processing framework -#include "ProcessHelper.h" -#include "DeboneProcess.h" -#include <stdio.h> - - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -DeboneProcess::DeboneProcess() -{ - mNumBones = 0; - mNumBonesCanDoWithout = 0; - - mThreshold = AI_DEBONE_THRESHOLD; - mAllOrNone = false; -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -DeboneProcess::~DeboneProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool DeboneProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_Debone) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void DeboneProcess::SetupProperties(const Importer* pImp) -{ - // get the current value of the property - mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false; - mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void DeboneProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("DeboneProcess begin"); - - if(!pScene->mNumMeshes) { - return; - } - - std::vector<bool> splitList(pScene->mNumMeshes); - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { - splitList[a] = ConsiderMesh( pScene->mMeshes[a] ); - } - - int numSplits = 0; - - if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) { - for(unsigned int a = 0; a < pScene->mNumMeshes; a++) { - if(splitList[a]) { - numSplits++; - } - } - } - - if(numSplits) { - // we need to do something. Let's go. - //mSubMeshIndices.clear(); // really needed? - mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway - - // build a new array of meshes for the scene - std::vector<aiMesh*> meshes; - - for(unsigned int a=0;a<pScene->mNumMeshes;a++) - { - aiMesh* srcMesh = pScene->mMeshes[a]; - - std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes; - - if(splitList[a]) { - SplitMesh(srcMesh,newMeshes); - } - - // mesh was split - if(!newMeshes.empty()) { - unsigned int out = 0, in = srcMesh->mNumBones; - - // store new meshes and indices of the new meshes - for(unsigned int b=0;b<newMeshes.size();b++) { - const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0; - - aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0; - std::pair<unsigned int,aiNode*> push_pair(static_cast<unsigned int>(meshes.size()),theNode); - - mSubMeshIndices[a].push_back(push_pair); - meshes.push_back(newMeshes[b].first); - - out+=newMeshes[b].first->mNumBones; - } - - if(!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Removed %u bones. Input bones:", in - out, ". Output bones: ", out); - } - - // and destroy the source mesh. It should be completely contained inside the new submeshes - delete srcMesh; - } - else { - // Mesh is kept unchanged - store it's new place in the mesh array - mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(static_cast<unsigned int>(meshes.size()),(aiNode*)0)); - meshes.push_back(srcMesh); - } - } - - // rebuild the scene's mesh array - pScene->mNumMeshes = static_cast<unsigned int>(meshes.size()); - delete [] pScene->mMeshes; - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - std::copy( meshes.begin(), meshes.end(), pScene->mMeshes); - - // recurse through all nodes and translate the node's mesh indices to fit the new mesh array - UpdateNode( pScene->mRootNode); - } - - ASSIMP_LOG_DEBUG("DeboneProcess end"); -} - -// ------------------------------------------------------------------------------------------------ -// Counts bones total/removable in a given mesh. -bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh) -{ - if(!pMesh->HasBones()) { - return false; - } - - bool split = false; - - //interstitial faces not permitted - bool isInterstitialRequired = false; - - std::vector<bool> isBoneNecessary(pMesh->mNumBones,false); - std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX); - - const unsigned int cUnowned = UINT_MAX; - const unsigned int cCoowned = UINT_MAX-1; - - for(unsigned int i=0;i<pMesh->mNumBones;i++) { - for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) { - float w = pMesh->mBones[i]->mWeights[j].mWeight; - - if(w==0.0f) { - continue; - } - - unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId; - if(w>=mThreshold) { - - if(vertexBones[vid]!=cUnowned) { - if(vertexBones[vid]==i) //double entry - { - ASSIMP_LOG_WARN("Encountered double entry in bone weights"); - } - else //TODO: track attraction in order to break tie - { - vertexBones[vid] = cCoowned; - } - } - else vertexBones[vid] = i; - } - - if(!isBoneNecessary[i]) { - isBoneNecessary[i] = w<mThreshold; - } - } - - if(!isBoneNecessary[i]) { - isInterstitialRequired = true; - } - } - - if(isInterstitialRequired) { - for(unsigned int i=0;i<pMesh->mNumFaces;i++) { - unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]]; - - for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) { - unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]]; - - if(v!=w) { - if(v<pMesh->mNumBones) isBoneNecessary[v] = true; - if(w<pMesh->mNumBones) isBoneNecessary[w] = true; - } - } - } - } - - for(unsigned int i=0;i<pMesh->mNumBones;i++) { - if(!isBoneNecessary[i]) { - mNumBonesCanDoWithout++; - split = true; - } - - mNumBones++; - } - return split; -} - -// ------------------------------------------------------------------------------------------------ -// Splits the given mesh by bone count. -void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const -{ - // same deal here as ConsiderMesh basically - - std::vector<bool> isBoneNecessary(pMesh->mNumBones,false); - std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX); - - const unsigned int cUnowned = UINT_MAX; - const unsigned int cCoowned = UINT_MAX-1; - - for(unsigned int i=0;i<pMesh->mNumBones;i++) { - for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) { - float w = pMesh->mBones[i]->mWeights[j].mWeight; - - if(w==0.0f) { - continue; - } - - unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId; - - if(w>=mThreshold) { - if(vertexBones[vid]!=cUnowned) { - if(vertexBones[vid]==i) //double entry - { - ASSIMP_LOG_WARN("Encountered double entry in bone weights"); - } - else //TODO: track attraction in order to break tie - { - vertexBones[vid] = cCoowned; - } - } - else vertexBones[vid] = i; - } - - if(!isBoneNecessary[i]) { - isBoneNecessary[i] = w<mThreshold; - } - } - } - - unsigned int nFacesUnowned = 0; - - std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX); - std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0); - - for(unsigned int i=0;i<pMesh->mNumFaces;i++) { - unsigned int nInterstitial = 1; - - unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]]; - - for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) { - unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]]; - - if(v!=w) { - if(v<pMesh->mNumBones) isBoneNecessary[v] = true; - if(w<pMesh->mNumBones) isBoneNecessary[w] = true; - } - else nInterstitial++; - } - - if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) { - faceBones[i] = v; //primitive belongs to bone #v - facesPerBone[v]++; - } - else nFacesUnowned++; - } - - // invalidate any "cojoined" faces - for(unsigned int i=0;i<pMesh->mNumFaces;i++) { - if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]]) - { - ai_assert(facesPerBone[faceBones[i]]>0); - facesPerBone[faceBones[i]]--; - - nFacesUnowned++; - faceBones[i] = cUnowned; - } - } - - if(nFacesUnowned) { - std::vector<unsigned int> subFaces; - - for(unsigned int i=0;i<pMesh->mNumFaces;i++) { - if(faceBones[i]==cUnowned) { - subFaces.push_back(i); - } - } - - aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0); - std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0); - - poNewMeshes.push_back(push_pair); - } - - for(unsigned int i=0;i<pMesh->mNumBones;i++) { - - if(!isBoneNecessary[i]&&facesPerBone[i]>0) { - std::vector<unsigned int> subFaces; - - for(unsigned int j=0;j<pMesh->mNumFaces;j++) { - if(faceBones[j]==i) { - subFaces.push_back(j); - } - } - - unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES; - aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f); - - //Lifted from PretransformVertices.cpp - ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix); - std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]); - - poNewMeshes.push_back(push_pair); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Recursively updates the node's mesh list to account for the changed mesh list -void DeboneProcess::UpdateNode(aiNode* pNode) const -{ - // rebuild the node's mesh index list - - std::vector<unsigned int> newMeshList; - - // this will require two passes - - unsigned int m = static_cast<unsigned int>(pNode->mNumMeshes), n = static_cast<unsigned int>(mSubMeshIndices.size()); - - // first pass, look for meshes which have not moved - - for(unsigned int a=0;a<m;a++) { - - unsigned int srcIndex = pNode->mMeshes[a]; - const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex]; - unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size()); - - for(unsigned int b=0;b<nSubmeshes;b++) { - if(!subMeshes[b].second) { - newMeshList.push_back(subMeshes[b].first); - } - } - } - - // second pass, collect deboned meshes - - for(unsigned int a=0;a<n;a++) - { - const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a]; - unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size()); - - for(unsigned int b=0;b<nSubmeshes;b++) { - if(subMeshes[b].second == pNode) { - newMeshList.push_back(subMeshes[b].first); - } - } - } - - if( pNode->mNumMeshes > 0 ) { - delete [] pNode->mMeshes; pNode->mMeshes = NULL; - } - - pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size()); - - if(pNode->mNumMeshes) { - pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; - std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); - } - - // do that also recursively for all children - for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) { - UpdateNode( pNode->mChildren[a]); - } -} - -// ------------------------------------------------------------------------------------------------ -// Apply the node transformation to a mesh -void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const -{ - // Check whether we need to transform the coordinates at all - if (!mat.IsIdentity()) { - - if (mesh->HasPositions()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - mesh->mVertices[i] = mat * mesh->mVertices[i]; - } - } - if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) { - aiMatrix4x4 mWorldIT = mat; - mWorldIT.Inverse().Transpose(); - - // TODO: implement Inverse() for aiMatrix3x3 - aiMatrix3x3 m = aiMatrix3x3(mWorldIT); - - if (mesh->HasNormals()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize(); - } - } - if (mesh->HasTangentsAndBitangents()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize(); - mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize(); - } - } - } - } -} diff --git a/thirdparty/assimp/code/PostProcessing/DeboneProcess.h b/thirdparty/assimp/code/PostProcessing/DeboneProcess.h deleted file mode 100644 index 8b64c2acc6..0000000000 --- a/thirdparty/assimp/code/PostProcessing/DeboneProcess.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** Defines a post processing step to limit the number of bones affecting a single vertex. */ -#ifndef AI_DEBONEPROCESS_H_INC -#define AI_DEBONEPROCESS_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> -#include <assimp/scene.h> - -#include <vector> -#include <utility> - -#// Forward declarations -class DeboneTest; - -namespace Assimp { - -#if (!defined AI_DEBONE_THRESHOLD) -# define AI_DEBONE_THRESHOLD 1.0f -#endif // !! AI_DEBONE_THRESHOLD - -// --------------------------------------------------------------------------- -/** This post processing step removes bones nearly losslessly or according to -* a configured threshold. In order to remove the bone, the primitives affected by -* the bone are split from the mesh. The split off (new) mesh is boneless. At any -* point in time, bones without affect upon a given mesh are to be removed. -*/ -class DeboneProcess : public BaseProcess { -public: - DeboneProcess(); - ~DeboneProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. - * A bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - void SetupProperties(const Importer* pImp); - -protected: - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - /** Counts bones total/removable in a given mesh. - * @param pMesh The mesh to process. - */ - bool ConsiderMesh( const aiMesh* pMesh); - - /// Splits the given mesh by bone count. - /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split. - /// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary. - void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const; - - /// Recursively updates the node's mesh list to account for the changed mesh list - void UpdateNode(aiNode* pNode) const; - - // ------------------------------------------------------------------- - // Apply transformation to a mesh - void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const; - -public: - /** Number of bones present in the scene. */ - unsigned int mNumBones; - unsigned int mNumBonesCanDoWithout; - - float mThreshold; - bool mAllOrNone; - - /// Per mesh index: Array of indices of the new submeshes. - std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices; -}; - -} // end of namespace Assimp - -#endif // AI_DEBONEPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp deleted file mode 100644 index b11615bb82..0000000000 --- a/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to drop face -* normals for all imported faces. -*/ - - -#include "DropFaceNormalsProcess.h" -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/Exceptional.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -DropFaceNormalsProcess::DropFaceNormalsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -DropFaceNormalsProcess::~DropFaceNormalsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const { - return (pFlags & aiProcess_DropNormals) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void DropFaceNormalsProcess::Execute( aiScene* pScene) { - ASSIMP_LOG_DEBUG("DropFaceNormalsProcess begin"); - - if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { - throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); - } - - bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { - bHas |= this->DropMeshFaceNormals( pScene->mMeshes[a]); - } - if (bHas) { - ASSIMP_LOG_INFO("DropFaceNormalsProcess finished. " - "Face normals have been removed"); - } else { - ASSIMP_LOG_DEBUG("DropFaceNormalsProcess finished. " - "No normals were present"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -bool DropFaceNormalsProcess::DropMeshFaceNormals (aiMesh* pMesh) { - if (NULL == pMesh->mNormals) { - return false; - } - - delete[] pMesh->mNormals; - pMesh->mNormals = nullptr; - return true; -} diff --git a/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h deleted file mode 100644 index c710c5a5ee..0000000000 --- a/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to compute face normals for all loaded faces*/ -#ifndef AI_DROPFACENORMALPROCESS_H_INC -#define AI_DROPFACENORMALPROCESS_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** The DropFaceNormalsProcess computes face normals for all faces of all meshes -*/ -class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess { -public: - DropFaceNormalsProcess(); - ~DropFaceNormalsProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - -private: - bool DropMeshFaceNormals(aiMesh* pcMesh); -}; - -} // end of namespace Assimp - -#endif // !!AI_DROPFACENORMALPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp deleted file mode 100644 index 739382a057..0000000000 --- a/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#include "EmbedTexturesProcess.h" -#include <assimp/ParsingUtils.h> -#include "ProcessHelper.h" - -#include <fstream> - -using namespace Assimp; - -EmbedTexturesProcess::EmbedTexturesProcess() -: BaseProcess() { -} - -EmbedTexturesProcess::~EmbedTexturesProcess() { -} - -bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const { - return (pFlags & aiProcess_EmbedTextures) != 0; -} - -void EmbedTexturesProcess::SetupProperties(const Importer* pImp) { - mRootPath = pImp->GetPropertyString("sourceFilePath"); - mRootPath = mRootPath.substr(0, mRootPath.find_last_of("\\/") + 1u); -} - -void EmbedTexturesProcess::Execute(aiScene* pScene) { - if (pScene == nullptr || pScene->mRootNode == nullptr) return; - - aiString path; - - uint32_t embeddedTexturesCount = 0u; - - for (auto matId = 0u; matId < pScene->mNumMaterials; ++matId) { - auto material = pScene->mMaterials[matId]; - - for (auto ttId = 1u; ttId < AI_TEXTURE_TYPE_MAX; ++ttId) { - auto tt = static_cast<aiTextureType>(ttId); - auto texturesCount = material->GetTextureCount(tt); - - for (auto texId = 0u; texId < texturesCount; ++texId) { - material->GetTexture(tt, texId, &path); - if (path.data[0] == '*') continue; // Already embedded - - // Indeed embed - if (addTexture(pScene, path.data)) { - auto embeddedTextureId = pScene->mNumTextures - 1u; - ::ai_snprintf(path.data, 1024, "*%u", embeddedTextureId); - material->AddProperty(&path, AI_MATKEY_TEXTURE(tt, texId)); - embeddedTexturesCount++; - } - } - } - } - - ASSIMP_LOG_INFO_F("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." ); -} - -bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { - std::streampos imageSize = 0; - std::string imagePath = path; - - // Test path directly - std::ifstream file(imagePath, std::ios::binary | std::ios::ate); - if ((imageSize = file.tellg()) == std::streampos(-1)) { - ASSIMP_LOG_WARN_F("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); - - // Test path in root path - imagePath = mRootPath + path; - file.open(imagePath, std::ios::binary | std::ios::ate); - if ((imageSize = file.tellg()) == std::streampos(-1)) { - // Test path basename in root path - imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u); - file.open(imagePath, std::ios::binary | std::ios::ate); - if ((imageSize = file.tellg()) == std::streampos(-1)) { - ASSIMP_LOG_ERROR_F("EmbedTexturesProcess: Unable to embed texture: ", path, "."); - return false; - } - } - } - - aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)]; - file.seekg(0, std::ios::beg); - file.read(reinterpret_cast<char*>(imageContent), imageSize); - - // Enlarging the textures table - unsigned int textureId = pScene->mNumTextures++; - auto oldTextures = pScene->mTextures; - pScene->mTextures = new aiTexture*[pScene->mNumTextures]; - ::memmove(pScene->mTextures, oldTextures, sizeof(aiTexture*) * (pScene->mNumTextures - 1u)); - - // Add the new texture - auto pTexture = new aiTexture; - pTexture->mHeight = 0; // Means that this is still compressed - pTexture->mWidth = static_cast<uint32_t>(imageSize); - pTexture->pcData = imageContent; - - auto extension = path.substr(path.find_last_of('.') + 1u); - std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); - if (extension == "jpeg") { - extension = "jpg"; - } - - size_t len = extension.size(); - if (len > HINTMAXTEXTURELEN -1 ) { - len = HINTMAXTEXTURELEN - 1; - } - ::strncpy(pTexture->achFormatHint, extension.c_str(), len); - pScene->mTextures[textureId] = pTexture; - - return true; -} diff --git a/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h deleted file mode 100644 index 3c4b2eab4e..0000000000 --- a/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#pragma once - -#include "Common/BaseProcess.h" - -#include <string> - -struct aiNode; - -namespace Assimp { - -/** - * Force embedding of textures (using the path = "*1" convention). - * If a texture's file does not exist at the specified path - * (due, for instance, to an absolute path generated on another system), - * it will check if a file with the same name exists at the root folder - * of the imported model. And if so, it uses that. - */ -class ASSIMP_API EmbedTexturesProcess : public BaseProcess { -public: - /// The default class constructor. - EmbedTexturesProcess(); - - /// The class destructor. - virtual ~EmbedTexturesProcess(); - - /// Overwritten, @see BaseProcess - virtual bool IsActive(unsigned int pFlags) const; - - /// Overwritten, @see BaseProcess - virtual void SetupProperties(const Importer* pImp); - - /// Overwritten, @see BaseProcess - virtual void Execute(aiScene* pScene); - -private: - // Resolve the path and add the file content to the scene as a texture. - bool addTexture(aiScene* pScene, std::string path) const; - -private: - std::string mRootPath; -}; - -} // namespace Assimp diff --git a/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp b/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp deleted file mode 100644 index 50fac46dba..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file FindDegenerates.cpp - * @brief Implementation of the FindDegenerates post-process step. -*/ - - - -// internal headers -#include "ProcessHelper.h" -#include "FindDegenerates.h" -#include <assimp/Exceptional.h> - -using namespace Assimp; - -//remove mesh at position 'index' from the scene -static void removeMesh(aiScene* pScene, unsigned const index); -//correct node indices to meshes and remove references to deleted mesh -static void updateSceneGraph(aiNode* pNode, unsigned const index); - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -FindDegeneratesProcess::FindDegeneratesProcess() -: mConfigRemoveDegenerates( false ) -, mConfigCheckAreaOfTriangle( false ){ - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FindDegeneratesProcess::~FindDegeneratesProcess() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const { - return 0 != (pFlags & aiProcess_FindDegenerates); -} - -// ------------------------------------------------------------------------------------------------ -// Setup import configuration -void FindDegeneratesProcess::SetupProperties(const Importer* pImp) { - // Get the current value of AI_CONFIG_PP_FD_REMOVE - mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0)); - mConfigCheckAreaOfTriangle = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA) ); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void FindDegeneratesProcess::Execute( aiScene* pScene) { - ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin"); - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) - { - //Do not process point cloud, ExecuteOnMesh works only with faces data - if ((pScene->mMeshes[i]->mPrimitiveTypes != aiPrimitiveType::aiPrimitiveType_POINT) && ExecuteOnMesh(pScene->mMeshes[i])) { - removeMesh(pScene, i); - --i; //the current i is removed, do not skip the next one - } - } - ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished"); -} - -static void removeMesh(aiScene* pScene, unsigned const index) { - //we start at index and copy the pointers one position forward - //save the mesh pointer to delete it later - auto delete_me = pScene->mMeshes[index]; - for (unsigned i = index; i < pScene->mNumMeshes - 1; ++i) { - pScene->mMeshes[i] = pScene->mMeshes[i+1]; - } - pScene->mMeshes[pScene->mNumMeshes - 1] = nullptr; - --(pScene->mNumMeshes); - delete delete_me; - - //removing a mesh also requires updating all references to it in the scene graph - updateSceneGraph(pScene->mRootNode, index); -} - -static void updateSceneGraph(aiNode* pNode, unsigned const index) { - for (unsigned i = 0; i < pNode->mNumMeshes; ++i) { - if (pNode->mMeshes[i] > index) { - --(pNode->mMeshes[i]); - continue; - } - if (pNode->mMeshes[i] == index) { - for (unsigned j = i; j < pNode->mNumMeshes -1; ++j) { - pNode->mMeshes[j] = pNode->mMeshes[j+1]; - } - --(pNode->mNumMeshes); - --i; - continue; - } - } - //recurse to all children - for (unsigned i = 0; i < pNode->mNumChildren; ++i) { - updateSceneGraph(pNode->mChildren[i], index); - } -} - -static ai_real heron( ai_real a, ai_real b, ai_real c ) { - ai_real s = (a + b + c) / 2; - ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 ); - return area; -} - -static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) { - const ai_real lx = ( vB.x - vA.x ); - const ai_real ly = ( vB.y - vA.y ); - const ai_real lz = ( vB.z - vA.z ); - ai_real a = lx*lx + ly*ly + lz*lz; - ai_real d = pow( a, (ai_real)0.5 ); - - return d; -} - -static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) { - ai_real area = 0; - - aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] ); - aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] ); - aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] ); - - ai_real a( distance3D( vA, vB ) ); - ai_real b( distance3D( vB, vC ) ); - ai_real c( distance3D( vC, vA ) ); - area = heron( a, b, c ); - - return area; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported mesh -bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) { - mesh->mPrimitiveTypes = 0; - - std::vector<bool> remove_me; - if (mConfigRemoveDegenerates) { - remove_me.resize( mesh->mNumFaces, false ); - } - - unsigned int deg = 0, limit; - for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) { - aiFace& face = mesh->mFaces[a]; - bool first = true; - - // check whether the face contains degenerated entries - for (unsigned int i = 0; i < face.mNumIndices; ++i) { - // Polygons with more than 4 points are allowed to have double points, that is - // simulating polygons with holes just with concave polygons. However, - // double points may not come directly after another. - limit = face.mNumIndices; - if (face.mNumIndices > 4) { - limit = std::min( limit, i+2 ); - } - - for (unsigned int t = i+1; t < limit; ++t) { - if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) { - // we have found a matching vertex position - // remove the corresponding index from the array - --face.mNumIndices; - --limit; - for (unsigned int m = t; m < face.mNumIndices; ++m) { - face.mIndices[ m ] = face.mIndices[ m+1 ]; - } - --t; - - // NOTE: we set the removed vertex index to an unique value - // to make sure the developer gets notified when his - // application attempts to access this data. - face.mIndices[ face.mNumIndices ] = 0xdeadbeef; - - if(first) { - ++deg; - first = false; - } - - if ( mConfigRemoveDegenerates ) { - remove_me[ a ] = true; - goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby! - } - } - } - - if ( mConfigCheckAreaOfTriangle ) { - if ( face.mNumIndices == 3 ) { - ai_real area = calculateAreaOfTriangle( face, mesh ); - if ( area < 1e-6 ) { - if ( mConfigRemoveDegenerates ) { - remove_me[ a ] = true; - ++deg; - goto evil_jump_outside; - } - - // todo: check for index which is corrupt. - } - } - } - } - - // We need to update the primitive flags array of the mesh. - switch (face.mNumIndices) - { - case 1u: - mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - case 2u: - mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - case 3u: - mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - default: - mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - break; - }; -evil_jump_outside: - continue; - } - - // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import - if (mConfigRemoveDegenerates && deg) { - unsigned int n = 0; - for (unsigned int a = 0; a < mesh->mNumFaces; ++a) - { - aiFace& face_src = mesh->mFaces[a]; - if (!remove_me[a]) { - aiFace& face_dest = mesh->mFaces[n++]; - - // Do a manual copy, keep the index array - face_dest.mNumIndices = face_src.mNumIndices; - face_dest.mIndices = face_src.mIndices; - - if (&face_src != &face_dest) { - // clear source - face_src.mNumIndices = 0; - face_src.mIndices = nullptr; - } - } - else { - // Otherwise delete it if we don't need this face - delete[] face_src.mIndices; - face_src.mIndices = nullptr; - face_src.mNumIndices = 0; - } - } - // Just leave the rest of the array unreferenced, we don't care for now - mesh->mNumFaces = n; - if (!mesh->mNumFaces) { - //The whole mesh consists of degenerated faces - //signal upward, that this mesh should be deleted. - ASSIMP_LOG_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives"); - return true; - } - } - - if (deg && !DefaultLogger::isNullLogger()) { - ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives"); - } - return false; -} diff --git a/thirdparty/assimp/code/PostProcessing/FindDegenerates.h b/thirdparty/assimp/code/PostProcessing/FindDegenerates.h deleted file mode 100644 index 7a15e77cf1..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FindDegenerates.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to search all meshes for - degenerated faces */ -#ifndef AI_FINDDEGENERATESPROCESS_H_INC -#define AI_FINDDEGENERATESPROCESS_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> - -class FindDegeneratesProcessTest; -namespace Assimp { - - -// --------------------------------------------------------------------------- -/** FindDegeneratesProcess: Searches a mesh for degenerated triangles. -*/ -class ASSIMP_API FindDegeneratesProcess : public BaseProcess { -public: - FindDegeneratesProcess(); - ~FindDegeneratesProcess(); - - // ------------------------------------------------------------------- - // Check whether step is active - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - // Execute step on a given scene - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - // Setup import settings - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - // Execute step on a given mesh - ///@returns true if the current mesh should be deleted, false otherwise - bool ExecuteOnMesh( aiMesh* mesh); - - // ------------------------------------------------------------------- - /// @brief Enable the instant removal of degenerated primitives - /// @param enabled true for enabled. - void EnableInstantRemoval(bool enabled); - - // ------------------------------------------------------------------- - /// @brief Check whether instant removal is currently enabled - /// @return The instant removal state. - bool IsInstantRemoval() const; - - // ------------------------------------------------------------------- - /// @brief Enable the area check for triangles. - /// @param enabled true for enabled. - void EnableAreaCheck( bool enabled ); - - // ------------------------------------------------------------------- - /// @brief Check whether the area check is enabled. - /// @return The area check state. - bool isAreaCheckEnabled() const; - -private: - //! Configuration option: remove degenerates faces immediately - bool mConfigRemoveDegenerates; - //! Configuration option: check for area - bool mConfigCheckAreaOfTriangle; -}; - -inline -void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) { - mConfigRemoveDegenerates = enabled; -} - -inline -bool FindDegeneratesProcess::IsInstantRemoval() const { - return mConfigRemoveDegenerates; -} - -inline -void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) { - mConfigCheckAreaOfTriangle = enabled; -} - -inline -bool FindDegeneratesProcess::isAreaCheckEnabled() const { - return mConfigCheckAreaOfTriangle; -} - -} // Namespace Assimp - -#endif // !! AI_FINDDEGENERATESPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp deleted file mode 100644 index 64907458a1..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file FindInstancesProcess.cpp - * @brief Implementation of the aiProcess_FindInstances postprocessing step -*/ - - -#include "FindInstancesProcess.h" -#include <memory> -#include <stdio.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -FindInstancesProcess::FindInstancesProcess() -: configSpeedFlag (false) -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FindInstancesProcess::~FindInstancesProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool FindInstancesProcess::IsActive( unsigned int pFlags) const -{ - // FindInstances makes absolutely no sense together with PreTransformVertices - // fixme: spawn error message somewhere else? - return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices); -} - -// ------------------------------------------------------------------------------------------------ -// Setup properties for the step -void FindInstancesProcess::SetupProperties(const Importer* pImp) -{ - // AI_CONFIG_FAVOUR_SPEED - configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0)); -} - -// ------------------------------------------------------------------------------------------------ -// Compare the bones of two meshes -bool CompareBones(const aiMesh* orig, const aiMesh* inst) -{ - for (unsigned int i = 0; i < orig->mNumBones;++i) { - aiBone* aha = orig->mBones[i]; - aiBone* oha = inst->mBones[i]; - - if (aha->mNumWeights != oha->mNumWeights || - aha->mOffsetMatrix != oha->mOffsetMatrix) { - return false; - } - - // compare weight per weight --- - for (unsigned int n = 0; n < aha->mNumWeights;++n) { - if (aha->mWeights[n].mVertexId != oha->mWeights[n].mVertexId || - (aha->mWeights[n].mWeight - oha->mWeights[n].mWeight) < 10e-3f) { - return false; - } - } - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Update mesh indices in the node graph -void UpdateMeshIndices(aiNode* node, unsigned int* lookup) -{ - for (unsigned int n = 0; n < node->mNumMeshes;++n) - node->mMeshes[n] = lookup[node->mMeshes[n]]; - - for (unsigned int n = 0; n < node->mNumChildren;++n) - UpdateMeshIndices(node->mChildren[n],lookup); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void FindInstancesProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("FindInstancesProcess begin"); - if (pScene->mNumMeshes) { - - // use a pseudo hash for all meshes in the scene to quickly find - // the ones which are possibly equal. This step is executed early - // in the pipeline, so we could, depending on the file format, - // have several thousand small meshes. That's too much for a brute - // everyone-against-everyone check involving up to 10 comparisons - // each. - std::unique_ptr<uint64_t[]> hashes (new uint64_t[pScene->mNumMeshes]); - std::unique_ptr<unsigned int[]> remapping (new unsigned int[pScene->mNumMeshes]); - - unsigned int numMeshesOut = 0; - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - - aiMesh* inst = pScene->mMeshes[i]; - hashes[i] = GetMeshHash(inst); - - // Find an appropriate epsilon - // to compare position differences against - float epsilon = ComputePositionEpsilon(inst); - epsilon *= epsilon; - - for (int a = i-1; a >= 0; --a) { - if (hashes[i] == hashes[a]) - { - aiMesh* orig = pScene->mMeshes[a]; - if (!orig) - continue; - - // check for hash collision .. we needn't check - // the vertex format, it *must* match due to the - // (brilliant) construction of the hash - if (orig->mNumBones != inst->mNumBones || - orig->mNumFaces != inst->mNumFaces || - orig->mNumVertices != inst->mNumVertices || - orig->mMaterialIndex != inst->mMaterialIndex || - orig->mPrimitiveTypes != inst->mPrimitiveTypes) - continue; - - // up to now the meshes are equal. Now compare vertex positions, normals, - // tangents and bitangents using this epsilon. - if (orig->HasPositions()) { - if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon)) - continue; - } - if (orig->HasNormals()) { - if(!CompareArrays(orig->mNormals,inst->mNormals,orig->mNumVertices,epsilon)) - continue; - } - if (orig->HasTangentsAndBitangents()) { - if (!CompareArrays(orig->mTangents,inst->mTangents,orig->mNumVertices,epsilon) || - !CompareArrays(orig->mBitangents,inst->mBitangents,orig->mNumVertices,epsilon)) - continue; - } - - // use a constant epsilon for colors and UV coordinates - static const float uvEpsilon = 10e-4f; - { - unsigned int j, end = orig->GetNumUVChannels(); - for(j = 0; j < end; ++j) { - if (!orig->mTextureCoords[j]) { - continue; - } - if(!CompareArrays(orig->mTextureCoords[j],inst->mTextureCoords[j],orig->mNumVertices,uvEpsilon)) { - break; - } - } - if (j != end) { - continue; - } - } - { - unsigned int j, end = orig->GetNumColorChannels(); - for(j = 0; j < end; ++j) { - if (!orig->mColors[j]) { - continue; - } - if(!CompareArrays(orig->mColors[j],inst->mColors[j],orig->mNumVertices,uvEpsilon)) { - break; - } - } - if (j != end) { - continue; - } - } - - // These two checks are actually quite expensive and almost *never* required. - // Almost. That's why they're still here. But there's no reason to do them - // in speed-targeted imports. - if (!configSpeedFlag) { - - // It seems to be strange, but we really need to check whether the - // bones are identical too. Although it's extremely unprobable - // that they're not if control reaches here, we need to deal - // with unprobable cases, too. It could still be that there are - // equal shapes which are deformed differently. - if (!CompareBones(orig,inst)) - continue; - - // For completeness ... compare even the index buffers for equality - // face order & winding order doesn't care. Input data is in verbose format. - std::unique_ptr<unsigned int[]> ftbl_orig(new unsigned int[orig->mNumVertices]); - std::unique_ptr<unsigned int[]> ftbl_inst(new unsigned int[orig->mNumVertices]); - - for (unsigned int tt = 0; tt < orig->mNumFaces;++tt) { - aiFace& f = orig->mFaces[tt]; - for (unsigned int nn = 0; nn < f.mNumIndices;++nn) - ftbl_orig[f.mIndices[nn]] = tt; - - aiFace& f2 = inst->mFaces[tt]; - for (unsigned int nn = 0; nn < f2.mNumIndices;++nn) - ftbl_inst[f2.mIndices[nn]] = tt; - } - if (0 != ::memcmp(ftbl_inst.get(),ftbl_orig.get(),orig->mNumVertices*sizeof(unsigned int))) - continue; - } - - // We're still here. Or in other words: 'inst' is an instance of 'orig'. - // Place a marker in our list that we can easily update mesh indices. - remapping[i] = remapping[a]; - - // Delete the instanced mesh, we don't need it anymore - delete inst; - pScene->mMeshes[i] = NULL; - break; - } - } - - // If we didn't find a match for the current mesh: keep it - if (pScene->mMeshes[i]) { - remapping[i] = numMeshesOut++; - } - } - ai_assert(0 != numMeshesOut); - if (numMeshesOut != pScene->mNumMeshes) { - - // Collapse the meshes array by removing all NULL entries - for (unsigned int real = 0, i = 0; real < numMeshesOut; ++i) { - if (pScene->mMeshes[i]) - pScene->mMeshes[real++] = pScene->mMeshes[i]; - } - - // And update the node graph with our nice lookup table - UpdateMeshIndices(pScene->mRootNode,remapping.get()); - - // write to log - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F( "FindInstancesProcess finished. Found ", (pScene->mNumMeshes - numMeshesOut), " instances" ); - } - pScene->mNumMeshes = numMeshesOut; - } else { - ASSIMP_LOG_DEBUG("FindInstancesProcess finished. No instanced meshes found"); - } - } -} diff --git a/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h deleted file mode 100644 index 64b838d7cc..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file FindInstancesProcess.h - * @brief Declares the aiProcess_FindInstances post-process step - */ -#ifndef AI_FINDINSTANCES_H_INC -#define AI_FINDINSTANCES_H_INC - -#include "Common/BaseProcess.h" -#include "PostProcessing/ProcessHelper.h" - -class FindInstancesProcessTest; -namespace Assimp { - -// ------------------------------------------------------------------------------- -/** @brief Get a pseudo(!)-hash representing a mesh. - * - * The hash is built from number of vertices, faces, primitive types, - * .... but *not* from the real mesh data. The funcction is not a perfect hash. - * @param in Input mesh - * @return Hash. - */ -inline -uint64_t GetMeshHash(aiMesh* in) { - ai_assert(nullptr != in); - - // ... get an unique value representing the vertex format of the mesh - const unsigned int fhash = GetMeshVFormatUnique(in); - - // and bake it with number of vertices/faces/bones/matidx/ptypes - return ((uint64_t)fhash << 32u) | (( - (in->mNumBones << 16u) ^ (in->mNumVertices) ^ - (in->mNumFaces<<4u) ^ (in->mMaterialIndex<<15) ^ - (in->mPrimitiveTypes<<28)) & 0xffffffff ); -} - -// ------------------------------------------------------------------------------- -/** @brief Perform a component-wise comparison of two arrays - * - * @param first First array - * @param second Second array - * @param size Size of both arrays - * @param e Epsilon - * @return true if the arrays are identical - */ -inline -bool CompareArrays(const aiVector3D* first, const aiVector3D* second, - unsigned int size, float e) { - for (const aiVector3D* end = first+size; first != end; ++first,++second) { - if ( (*first - *second).SquareLength() >= e) - return false; - } - return true; -} - -// and the same for colors ... -inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second, - unsigned int size, float e) -{ - for (const aiColor4D* end = first+size; first != end; ++first,++second) { - if ( GetColorDifference(*first,*second) >= e) - return false; - } - return true; -} - -// --------------------------------------------------------------------------- -/** @brief A post-processing steps to search for instanced meshes -*/ -class FindInstancesProcess : public BaseProcess -{ -public: - - FindInstancesProcess(); - ~FindInstancesProcess(); - -public: - // ------------------------------------------------------------------- - // Check whether step is active in given flags combination - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - // Execute step on a given scene - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - // Setup properties prior to executing the process - void SetupProperties(const Importer* pImp); - -private: - - bool configSpeedFlag; - -}; // ! end class FindInstancesProcess -} // ! end namespace Assimp - -#endif // !! AI_FINDINSTANCES_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp deleted file mode 100644 index 016884c6e7..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp +++ /dev/null @@ -1,423 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to search an importer's output - for data that is obviously invalid */ - - - -#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS - -// internal headers -#include "FindInvalidDataProcess.h" -#include "ProcessHelper.h" - -#include <assimp/Exceptional.h> -#include <assimp/qnan.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -FindInvalidDataProcess::FindInvalidDataProcess() -: configEpsilon(0.0) -, mIgnoreTexCoods( false ){ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FindInvalidDataProcess::~FindInvalidDataProcess() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const { - return 0 != (pFlags & aiProcess_FindInvalidData); -} - -// ------------------------------------------------------------------------------------------------ -// Setup import configuration -void FindInvalidDataProcess::SetupProperties(const Importer* pImp) { - // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY - configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f)); - mIgnoreTexCoods = pImp->GetPropertyBool(AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS, false); -} - -// ------------------------------------------------------------------------------------------------ -// Update mesh references in the node graph -void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping) { - if (node->mNumMeshes) { - unsigned int out = 0; - for (unsigned int a = 0; a < node->mNumMeshes;++a) { - - unsigned int ref = node->mMeshes[a]; - if (UINT_MAX != (ref = meshMapping[ref])) { - node->mMeshes[out++] = ref; - } - } - // just let the members that are unused, that's much cheaper - // than a full array realloc'n'copy party ... - if(!(node->mNumMeshes = out)) { - - delete[] node->mMeshes; - node->mMeshes = NULL; - } - } - // recursively update all children - for (unsigned int i = 0; i < node->mNumChildren;++i) { - UpdateMeshReferences(node->mChildren[i],meshMapping); - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void FindInvalidDataProcess::Execute( aiScene* pScene) { - ASSIMP_LOG_DEBUG("FindInvalidDataProcess begin"); - - bool out = false; - std::vector<unsigned int> meshMapping(pScene->mNumMeshes); - unsigned int real = 0; - - // Process meshes - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { - - int result; - if ((result = ProcessMesh( pScene->mMeshes[a]))) { - out = true; - - if (2 == result) { - // remove this mesh - delete pScene->mMeshes[a]; - AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]); - - meshMapping[a] = UINT_MAX; - continue; - } - } - pScene->mMeshes[real] = pScene->mMeshes[a]; - meshMapping[a] = real++; - } - - // Process animations - for (unsigned int a = 0; a < pScene->mNumAnimations;++a) { - ProcessAnimation( pScene->mAnimations[a]); - } - - - if (out) { - if ( real != pScene->mNumMeshes) { - if (!real) { - throw DeadlyImportError("No meshes remaining"); - } - - // we need to remove some meshes. - // therefore we'll also need to remove all references - // to them from the scenegraph - UpdateMeshReferences(pScene->mRootNode,meshMapping); - pScene->mNumMeshes = real; - } - - ASSIMP_LOG_INFO("FindInvalidDataProcess finished. Found issues ..."); - } else { - ASSIMP_LOG_DEBUG("FindInvalidDataProcess finished. Everything seems to be OK."); - } -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -const char* ValidateArrayContents(const T* /*arr*/, unsigned int /*size*/, - const std::vector<bool>& /*dirtyMask*/, bool /*mayBeIdentical = false*/, bool /*mayBeZero = true*/) -{ - return nullptr; -} - -// ------------------------------------------------------------------------------------------------ -template <> -inline -const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size, - const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero ) { - bool b = false; - unsigned int cnt = 0; - for (unsigned int i = 0; i < size;++i) { - - if (dirtyMask.size() && dirtyMask[i]) { - continue; - } - ++cnt; - - const aiVector3D& v = arr[i]; - if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) { - return "INF/NAN was found in a vector component"; - } - if (!mayBeZero && !v.x && !v.y && !v.z ) { - return "Found zero-length vector"; - } - if (i && v != arr[i-1])b = true; - } - if (cnt > 1 && !b && !mayBeIdentical) { - return "All vectors are identical"; - } - return nullptr; -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -bool ProcessArray(T*& in, unsigned int num,const char* name, - const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) { - const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero); - if (err) { - ASSIMP_LOG_ERROR_F( "FindInvalidDataProcess fails on mesh ", name, ": ", err); - delete[] in; - in = NULL; - return true; - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, ai_real epsilon); - -// ------------------------------------------------------------------------------------------------ -AI_FORCE_INLINE bool EpsilonCompare(ai_real n, ai_real s, ai_real epsilon) { - return std::fabs(n-s)>epsilon; -} - -// ------------------------------------------------------------------------------------------------ -template <> -bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, ai_real epsilon) { - return - EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && - EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && - EpsilonCompare(n.mValue.z,s.mValue.z,epsilon); -} - -// ------------------------------------------------------------------------------------------------ -template <> -bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, ai_real epsilon) { - return - EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && - EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && - EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) && - EpsilonCompare(n.mValue.w,s.mValue.w,epsilon); -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -bool AllIdentical(T* in, unsigned int num, ai_real epsilon) { - if (num <= 1) { - return true; - } - - if (fabs(epsilon) > 0.f) { - for (unsigned int i = 0; i < num-1;++i) { - if (!EpsilonCompare(in[i],in[i+1],epsilon)) { - return false; - } - } - } else { - for (unsigned int i = 0; i < num-1;++i) { - if (in[i] != in[i+1]) { - return false; - } - } - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Search an animation for invalid content -void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim) { - // Process all animation channels - for ( unsigned int a = 0; a < anim->mNumChannels; ++a ) { - ProcessAnimationChannel( anim->mChannels[a]); - } -} - -// ------------------------------------------------------------------------------------------------ -void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) { - ai_assert( nullptr != anim ); - if (anim->mNumPositionKeys == 0 && anim->mNumRotationKeys == 0 && anim->mNumScalingKeys == 0) { - ai_assert_entry(); - return; - } - - // Check whether all values in a tracks are identical - in this case - // we can remove al keys except one. - // POSITIONS - int i = 0; - if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon)) { - aiVectorKey v = anim->mPositionKeys[0]; - - // Reallocate ... we need just ONE element, it makes no sense to reuse the array - delete[] anim->mPositionKeys; - anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = 1]; - anim->mPositionKeys[0] = v; - i = 1; - } - - // ROTATIONS - if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon)) { - aiQuatKey v = anim->mRotationKeys[0]; - - // Reallocate ... we need just ONE element, it makes no sense to reuse the array - delete[] anim->mRotationKeys; - anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = 1]; - anim->mRotationKeys[0] = v; - i = 1; - } - - // SCALINGS - if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon)) { - aiVectorKey v = anim->mScalingKeys[0]; - - // Reallocate ... we need just ONE element, it makes no sense to reuse the array - delete[] anim->mScalingKeys; - anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = 1]; - anim->mScalingKeys[0] = v; - i = 1; - } - if ( 1 == i ) { - ASSIMP_LOG_WARN("Simplified dummy tracks with just one key"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Search a mesh for invalid contents -int FindInvalidDataProcess::ProcessMesh(aiMesh* pMesh) -{ - bool ret = false; - std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0); - - // Ignore elements that are not referenced by vertices. - // (they are, for example, caused by the FindDegenerates step) - for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) { - const aiFace& f = pMesh->mFaces[m]; - - for (unsigned int i = 0; i < f.mNumIndices; ++i) { - dirtyMask[f.mIndices[i]] = false; - } - } - - // Process vertex positions - if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) { - ASSIMP_LOG_ERROR("Deleting mesh: Unable to continue without vertex positions"); - - return 2; - } - - // process texture coordinates - if (!mIgnoreTexCoods) { - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) { - if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) { - pMesh->mNumUVComponents[i] = 0; - - // delete all subsequent texture coordinate sets. - for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { - delete[] pMesh->mTextureCoords[a]; - pMesh->mTextureCoords[a] = NULL; - pMesh->mNumUVComponents[a] = 0; - } - - ret = true; - } - } - } - - // -- we don't validate vertex colors, it's difficult to say whether - // they are invalid or not. - - // Normals and tangents are undefined for point and line faces. - if (pMesh->mNormals || pMesh->mTangents) { - - if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes || - aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) - { - if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes || - aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes) - { - // We need to update the lookup-table - for (unsigned int m = 0; m < pMesh->mNumFaces;++m) { - const aiFace& f = pMesh->mFaces[ m ]; - - if (f.mNumIndices < 3) { - dirtyMask[f.mIndices[0]] = true; - if (f.mNumIndices == 2) { - dirtyMask[f.mIndices[1]] = true; - } - } - } - } - // Normals, tangents and bitangents are undefined for - // the whole mesh (and should not even be there) - else { - return ret; - } - } - - // Process mesh normals - if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices, - "normals",dirtyMask,true,false)) - ret = true; - - // Process mesh tangents - if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) { - delete[] pMesh->mBitangents; pMesh->mBitangents = NULL; - ret = true; - } - - // Process mesh bitangents - if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) { - delete[] pMesh->mTangents; pMesh->mTangents = NULL; - ret = true; - } - } - return ret ? 1 : 0; -} - -#endif // !! ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h deleted file mode 100644 index ce7375f34f..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to search an importer's output - * for data that is obviously invalid - */ -#ifndef AI_FINDINVALIDDATA_H_INC -#define AI_FINDINVALIDDATA_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/types.h> -#include <assimp/anim.h> - -struct aiMesh; - -class FindInvalidDataProcessTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** The FindInvalidData post-processing step. It searches the mesh data - * for parts that are obviously invalid and removes them. - * - * Originally this was a workaround for some models written by Blender - * which have zero normal vectors. */ -class ASSIMP_API FindInvalidDataProcess : public BaseProcess { -public: - FindInvalidDataProcess(); - ~FindInvalidDataProcess(); - - // ------------------------------------------------------------------- - // - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - // Setup import settings - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - // Run the step - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - /** Executes the post-processing step on the given mesh - * @param pMesh The mesh to process. - * @return 0 - nothing, 1 - removed sth, 2 - please delete me */ - int ProcessMesh( aiMesh* pMesh); - - // ------------------------------------------------------------------- - /** Executes the post-processing step on the given animation - * @param anim The animation to process. */ - void ProcessAnimation (aiAnimation* anim); - - // ------------------------------------------------------------------- - /** Executes the post-processing step on the given anim channel - * @param anim The animation channel to process.*/ - void ProcessAnimationChannel (aiNodeAnim* anim); - -private: - ai_real configEpsilon; - bool mIgnoreTexCoods; -}; - -} // end of namespace Assimp - -#endif // AI_AI_FINDINVALIDDATA_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp deleted file mode 100644 index bbbe6899b4..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to invert - * all normals in meshes with infacing normals. - */ - -// internal headers -#include "FixNormalsStep.h" -#include <assimp/StringUtils.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <stdio.h> - - -using namespace Assimp; - - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -FixInfacingNormalsProcess::FixInfacingNormalsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -FixInfacingNormalsProcess::~FixInfacingNormalsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_FixInfacingNormals) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void FixInfacingNormalsProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess begin"); - - bool bHas( false ); - for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) { - if (ProcessMesh(pScene->mMeshes[a], a)) { - bHas = true; - } - } - - if (bHas) { - ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess finished. Found issues."); - } else { - ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess finished. No changes to the scene."); - } -} - -// ------------------------------------------------------------------------------------------------ -// Apply the step to the mesh -bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index) -{ - ai_assert(nullptr != pcMesh); - - // Nothing to do if there are no model normals - if (!pcMesh->HasNormals()) { - return false; - } - - // Compute the bounding box of both the model vertices + normals and - // the unmodified model vertices. Then check whether the first BB - // is smaller than the second. In this case we can assume that the - // normals need to be flipped, although there are a few special cases .. - // convex, concave, planar models ... - - aiVector3D vMin0 (1e10f,1e10f,1e10f); - aiVector3D vMin1 (1e10f,1e10f,1e10f); - aiVector3D vMax0 (-1e10f,-1e10f,-1e10f); - aiVector3D vMax1 (-1e10f,-1e10f,-1e10f); - - for (unsigned int i = 0; i < pcMesh->mNumVertices;++i) - { - vMin1.x = std::min(vMin1.x,pcMesh->mVertices[i].x); - vMin1.y = std::min(vMin1.y,pcMesh->mVertices[i].y); - vMin1.z = std::min(vMin1.z,pcMesh->mVertices[i].z); - - vMax1.x = std::max(vMax1.x,pcMesh->mVertices[i].x); - vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y); - vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z); - - const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i]; - - vMin0.x = std::min(vMin0.x,vWithNormal.x); - vMin0.y = std::min(vMin0.y,vWithNormal.y); - vMin0.z = std::min(vMin0.z,vWithNormal.z); - - vMax0.x = std::max(vMax0.x,vWithNormal.x); - vMax0.y = std::max(vMax0.y,vWithNormal.y); - vMax0.z = std::max(vMax0.z,vWithNormal.z); - } - - const float fDelta0_x = (vMax0.x - vMin0.x); - const float fDelta0_y = (vMax0.y - vMin0.y); - const float fDelta0_z = (vMax0.z - vMin0.z); - - const float fDelta1_x = (vMax1.x - vMin1.x); - const float fDelta1_y = (vMax1.y - vMin1.y); - const float fDelta1_z = (vMax1.z - vMin1.z); - - // Check whether the boxes are overlapping - if ((fDelta0_x > 0.0f) != (fDelta1_x > 0.0f))return false; - if ((fDelta0_y > 0.0f) != (fDelta1_y > 0.0f))return false; - if ((fDelta0_z > 0.0f) != (fDelta1_z > 0.0f))return false; - - // Check whether this is a planar surface - const float fDelta1_yz = fDelta1_y * fDelta1_z; - - if (fDelta1_x < 0.05f * std::sqrt( fDelta1_yz ))return false; - if (fDelta1_y < 0.05f * std::sqrt( fDelta1_z * fDelta1_x ))return false; - if (fDelta1_z < 0.05f * std::sqrt( fDelta1_y * fDelta1_x ))return false; - - // now compare the volumes of the bounding boxes - if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < std::fabs(fDelta1_x * fDelta1_yz)) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Mesh ", index, ": Normals are facing inwards (or the mesh is planar)", index); - } - - // Invert normals - for (unsigned int i = 0; i < pcMesh->mNumVertices;++i) - pcMesh->mNormals[i] *= -1.0f; - - // ... and flip faces - for (unsigned int i = 0; i < pcMesh->mNumFaces;++i) - { - aiFace& face = pcMesh->mFaces[i]; - for( unsigned int b = 0; b < face.mNumIndices / 2; b++) - std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]); - } - return true; - } - return false; -} diff --git a/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h deleted file mode 100644 index f60ce596a4..0000000000 --- a/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - - -/** @file Defines a post processing step to fix infacing normals */ -#ifndef AI_FIXNORMALSPROCESS_H_INC -#define AI_FIXNORMALSPROCESS_H_INC - -#include "Common/BaseProcess.h" - -struct aiMesh; - -namespace Assimp -{ - -// --------------------------------------------------------------------------- -/** The FixInfacingNormalsProcess tries to determine whether the normal - * vectors of an object are facing inwards. In this case they will be - * flipped. - */ -class FixInfacingNormalsProcess : public BaseProcess { -public: - FixInfacingNormalsProcess(); - ~FixInfacingNormalsProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - -protected: - - // ------------------------------------------------------------------- - /** Executes the step on the given mesh - * @param pMesh The mesh to process. - */ - bool ProcessMesh( aiMesh* pMesh, unsigned int index); -}; - -} // end of namespace Assimp - -#endif // AI_FIXNORMALSPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp deleted file mode 100644 index c013454fc3..0000000000 --- a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -#ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS - -#include "PostProcessing/GenBoundingBoxesProcess.h" - -#include <assimp/postprocess.h> -#include <assimp/scene.h> - -namespace Assimp { - -GenBoundingBoxesProcess::GenBoundingBoxesProcess() -: BaseProcess() { - -} - -GenBoundingBoxesProcess::~GenBoundingBoxesProcess() { - // empty -} - -bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const { - return 0 != ( pFlags & aiProcess_GenBoundingBoxes ); -} - -void checkMesh(aiMesh* mesh, aiVector3D& min, aiVector3D& max) { - ai_assert(nullptr != mesh); - - if (0 == mesh->mNumVertices) { - return; - } - - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - const aiVector3D &pos = mesh->mVertices[i]; - if (pos.x < min.x) { - min.x = pos.x; - } - if (pos.y < min.y) { - min.y = pos.y; - } - if (pos.z < min.z) { - min.z = pos.z; - } - - if (pos.x > max.x) { - max.x = pos.x; - } - if (pos.y > max.y) { - max.y = pos.y; - } - if (pos.z > max.z) { - max.z = pos.z; - } - } -} - -void GenBoundingBoxesProcess::Execute(aiScene* pScene) { - if (nullptr == pScene) { - return; - } - - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - aiMesh* mesh = pScene->mMeshes[i]; - if (nullptr == mesh) { - continue; - } - - aiVector3D min(999999, 999999, 999999), max(-999999, -999999, -999999); - checkMesh(mesh, min, max); - mesh->mAABB.mMin = min; - mesh->mAABB.mMax = max; - } -} - -} // Namespace Assimp - -#endif // ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h deleted file mode 100644 index 4b43c82a42..0000000000 --- a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Defines a post-processing step to generate Axis-aligned bounding - * volumes for all meshes. - */ - -#pragma once - -#ifndef AI_GENBOUNDINGBOXESPROCESS_H_INC -#define AI_GENBOUNDINGBOXESPROCESS_H_INC - -#ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS - -#include "Common/BaseProcess.h" - -namespace Assimp { - -/** Post-processing process to find axis-aligned bounding volumes for amm meshes - * used in a scene - */ -class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess { -public: - /// The class constructor. - GenBoundingBoxesProcess(); - /// The class destructor. - ~GenBoundingBoxesProcess(); - /// Will return true, if aiProcess_GenBoundingBoxes is defined. - bool IsActive(unsigned int pFlags) const override; - /// The execution callback. - void Execute(aiScene* pScene) override; -}; - -} // Namespace Assimp - -#endif // #ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS - -#endif // AI_GENBOUNDINGBOXESPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp deleted file mode 100644 index 028334dec7..0000000000 --- a/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to generate face -* normals for all imported faces. -*/ - - -#include "GenFaceNormalsProcess.h" -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/Exceptional.h> -#include <assimp/qnan.h> - - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -GenFaceNormalsProcess::GenFaceNormalsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -GenFaceNormalsProcess::~GenFaceNormalsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const { - force_ = (pFlags & aiProcess_ForceGenNormals) != 0; - return (pFlags & aiProcess_GenNormals) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void GenFaceNormalsProcess::Execute( aiScene* pScene) { - ASSIMP_LOG_DEBUG("GenFaceNormalsProcess begin"); - - if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { - throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); - } - - bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { - if(this->GenMeshFaceNormals( pScene->mMeshes[a])) { - bHas = true; - } - } - if (bHas) { - ASSIMP_LOG_INFO("GenFaceNormalsProcess finished. " - "Face normals have been calculated"); - } else { - ASSIMP_LOG_DEBUG("GenFaceNormalsProcess finished. " - "Normals are already there"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh) -{ - if (NULL != pMesh->mNormals) { - if (force_) delete[] pMesh->mNormals; - else return false; - } - - // If the mesh consists of lines and/or points but not of - // triangles or higher-order polygons the normal vectors - // are undefined. - if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) { - ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes"); - return false; - } - - // allocate an array to hold the output normals - pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - const float qnan = get_qnan(); - - // iterate through all faces and compute per-face normals but store them per-vertex. - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - const aiFace& face = pMesh->mFaces[a]; - if (face.mNumIndices < 3) { - // either a point or a line -> no well-defined normal vector - for (unsigned int i = 0;i < face.mNumIndices;++i) { - pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan); - } - continue; - } - - const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]]; - const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]]; - const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]]; - const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); - - for (unsigned int i = 0;i < face.mNumIndices;++i) { - pMesh->mNormals[face.mIndices[i]] = vNor; - } - } - return true; -} diff --git a/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h deleted file mode 100644 index c641fd6353..0000000000 --- a/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to compute face normals for all loaded faces*/ -#ifndef AI_GENFACENORMALPROCESS_H_INC -#define AI_GENFACENORMALPROCESS_H_INC - -#include "Common/BaseProcess.h" -#include <assimp/mesh.h> - -namespace Assimp -{ - -// --------------------------------------------------------------------------- -/** The GenFaceNormalsProcess computes face normals for all faces of all meshes -*/ -class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess -{ -public: - - GenFaceNormalsProcess(); - ~GenFaceNormalsProcess(); - -public: - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - -private: - bool GenMeshFaceNormals(aiMesh* pcMesh); - mutable bool force_ = false; -}; - -} // end of namespace Assimp - -#endif // !!AI_GENFACENORMALPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp deleted file mode 100644 index 3f6c2f86bd..0000000000 --- a/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to generate face -* normals for all imported faces. -*/ - - - -// internal headers -#include "GenVertexNormalsProcess.h" -#include "ProcessHelper.h" -#include <assimp/Exceptional.h> -#include <assimp/qnan.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -GenVertexNormalsProcess::GenVertexNormalsProcess() -: configMaxAngle( AI_DEG_TO_RAD( 175.f ) ) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -GenVertexNormalsProcess::~GenVertexNormalsProcess() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const -{ - force_ = (pFlags & aiProcess_ForceGenNormals) != 0; - return (pFlags & aiProcess_GenSmoothNormals) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void GenVertexNormalsProcess::SetupProperties(const Importer* pImp) -{ - // Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property - configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,(ai_real)175.0); - configMaxAngle = AI_DEG_TO_RAD(std::max(std::min(configMaxAngle,(ai_real)175.0),(ai_real)0.0)); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void GenVertexNormalsProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("GenVertexNormalsProcess begin"); - - if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { - throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); - } - - bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) { - if(GenMeshVertexNormals( pScene->mMeshes[a],a)) - bHas = true; - } - - if (bHas) { - ASSIMP_LOG_INFO("GenVertexNormalsProcess finished. " - "Vertex normals have been calculated"); - } else { - ASSIMP_LOG_DEBUG("GenVertexNormalsProcess finished. " - "Normals are already there"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex) -{ - if (NULL != pMesh->mNormals) { - if (force_) delete[] pMesh->mNormals; - else return false; - } - - // If the mesh consists of lines and/or points but not of - // triangles or higher-order polygons the normal vectors - // are undefined. - if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) - { - ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes"); - return false; - } - - // Allocate the array to hold the output normals - const float qnan = std::numeric_limits<ai_real>::quiet_NaN(); - pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - - // Compute per-face normals but store them per-vertex - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) - { - const aiFace& face = pMesh->mFaces[a]; - if (face.mNumIndices < 3) - { - // either a point or a line -> no normal vector - for (unsigned int i = 0;i < face.mNumIndices;++i) { - pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan); - } - - continue; - } - - const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]]; - const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]]; - const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]]; - const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); - - for (unsigned int i = 0;i < face.mNumIndices;++i) { - pMesh->mNormals[face.mIndices[i]] = vNor; - } - } - - // Set up a SpatialSort to quickly find all vertices close to a given position - // check whether we can reuse the SpatialSort of a previous step. - SpatialSort* vertexFinder = NULL; - SpatialSort _vertexFinder; - ai_real posEpsilon = ai_real( 1e-5 ); - if (shared) { - std::vector<std::pair<SpatialSort,ai_real> >* avf; - shared->GetProperty(AI_SPP_SPATIAL_SORT,avf); - if (avf) - { - std::pair<SpatialSort,ai_real>& blubb = avf->operator [] (meshIndex); - vertexFinder = &blubb.first; - posEpsilon = blubb.second; - } - } - if (!vertexFinder) { - _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D)); - vertexFinder = &_vertexFinder; - posEpsilon = ComputePositionEpsilon(pMesh); - } - std::vector<unsigned int> verticesFound; - aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices]; - - if (configMaxAngle >= AI_DEG_TO_RAD( 175.f )) { - // There is no angle limit. Thus all vertices with positions close - // to each other will receive the same vertex normal. This allows us - // to optimize the whole algorithm a little bit ... - std::vector<bool> abHad(pMesh->mNumVertices,false); - for (unsigned int i = 0; i < pMesh->mNumVertices;++i) { - if (abHad[i]) { - continue; - } - - // Get all vertices that share this one ... - vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound); - - aiVector3D pcNor; - for (unsigned int a = 0; a < verticesFound.size(); ++a) { - const aiVector3D& v = pMesh->mNormals[verticesFound[a]]; - if (is_not_qnan(v.x))pcNor += v; - } - pcNor.NormalizeSafe(); - - // Write the smoothed normal back to all affected normals - for (unsigned int a = 0; a < verticesFound.size(); ++a) - { - unsigned int vidx = verticesFound[a]; - pcNew[vidx] = pcNor; - abHad[vidx] = true; - } - } - } - // Slower code path if a smooth angle is set. There are many ways to achieve - // the effect, this one is the most straightforward one. - else { - const ai_real fLimit = std::cos(configMaxAngle); - for (unsigned int i = 0; i < pMesh->mNumVertices;++i) { - // Get all vertices that share this one ... - vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound); - - aiVector3D vr = pMesh->mNormals[i]; - - aiVector3D pcNor; - for (unsigned int a = 0; a < verticesFound.size(); ++a) { - aiVector3D v = pMesh->mNormals[verticesFound[a]]; - - // Check whether the angle between the two normals is not too large. - // Skip the angle check on our own normal to avoid false negatives - // (v*v is not guaranteed to be 1.0 for all unit vectors v) - if (is_not_qnan(v.x) && (verticesFound[a] == i || (v * vr >= fLimit))) - pcNor += v; - } - pcNew[i] = pcNor.NormalizeSafe(); - } - } - - delete[] pMesh->mNormals; - pMesh->mNormals = pcNew; - - return true; -} diff --git a/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h deleted file mode 100644 index 2ceee17e85..0000000000 --- a/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to compute vertex normals - for all loaded vertizes */ -#ifndef AI_GENVERTEXNORMALPROCESS_H_INC -#define AI_GENVERTEXNORMALPROCESS_H_INC - -#include "Common/assbin_chunks.h" -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> - -// Forward declarations -class GenNormalsTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** The GenFaceNormalsProcess computes vertex normals for all vertices -*/ -class ASSIMP_API GenVertexNormalsProcess : public BaseProcess { -public: - GenVertexNormalsProcess(); - ~GenVertexNormalsProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. - * A bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - - // setter for configMaxAngle - inline void SetMaxSmoothAngle(ai_real f) { - configMaxAngle =f; - } - - // ------------------------------------------------------------------- - /** Computes normals for a specific mesh - * @param pcMesh Mesh - * @param meshIndex Index of the mesh - * @return true if vertex normals have been computed - */ - bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex); - -private: - /** Configuration option: maximum smoothing angle, in radians*/ - ai_real configMaxAngle; - mutable bool force_ = false; -}; - -} // end of namespace Assimp - -#endif // !!AI_GENVERTEXNORMALPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp deleted file mode 100644 index d0a016fa42..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to improve the cache locality of a mesh. - * <br> - * The algorithm is roughly basing on this paper: - * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf - * .. although overdraw reduction isn't implemented yet ... - */ - -// internal headers -#include "PostProcessing/ImproveCacheLocality.h" -#include "Common/VertexTriangleAdjacency.h" - -#include <assimp/StringUtils.h> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> -#include <stdio.h> -#include <stack> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() -: mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const { - return (pFlags & aiProcess_ImproveCacheLocality) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Setup configuration -void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp) { - // AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer - mConfigCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void ImproveCacheLocalityProcess::Execute( aiScene* pScene) { - if (!pScene->mNumMeshes) { - ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes"); - return; - } - - ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess begin"); - - float out = 0.f; - unsigned int numf = 0, numm = 0; - for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ){ - const float res = ProcessMesh( pScene->mMeshes[a],a); - if (res) { - numf += pScene->mMeshes[a]->mNumFaces; - out += res; - ++numm; - } - } - if (!DefaultLogger::isNullLogger()) { - if (numf > 0) { - ASSIMP_LOG_INFO_F("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf); - } - ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess finished. "); - } -} - -// ------------------------------------------------------------------------------------------------ -// Improves the cache coherency of a specific mesh -ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum) { - // TODO: rewrite this to use std::vector or boost::shared_array - ai_assert(nullptr != pMesh); - - // Check whether the input data is valid - // - there must be vertices and faces - // - all faces must be triangulated or we can't operate on them - if (!pMesh->HasFaces() || !pMesh->HasPositions()) - return static_cast<ai_real>(0.f); - - if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) { - ASSIMP_LOG_ERROR("This algorithm works on triangle meshes only"); - return static_cast<ai_real>(0.f); - } - - if(pMesh->mNumVertices <= mConfigCacheDepth) { - return static_cast<ai_real>(0.f); - } - - ai_real fACMR = 3.f; - const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces; - - // Input ACMR is for logging purposes only - if (!DefaultLogger::isNullLogger()) { - - unsigned int* piFIFOStack = new unsigned int[mConfigCacheDepth]; - memset(piFIFOStack,0xff,mConfigCacheDepth*sizeof(unsigned int)); - unsigned int* piCur = piFIFOStack; - const unsigned int* const piCurEnd = piFIFOStack + mConfigCacheDepth; - - // count the number of cache misses - unsigned int iCacheMisses = 0; - for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace) { - for (unsigned int qq = 0; qq < 3;++qq) { - bool bInCache = false; - for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp) { - if (*pp == pcFace->mIndices[qq]) { - // the vertex is in cache - bInCache = true; - break; - } - } - if (!bInCache) { - ++iCacheMisses; - if (piCurEnd == piCur) { - piCur = piFIFOStack; - } - *piCur++ = pcFace->mIndices[qq]; - } - } - } - delete[] piFIFOStack; - fACMR = (ai_real) iCacheMisses / pMesh->mNumFaces; - if (3.0 == fACMR) { - char szBuff[128]; // should be sufficiently large in every case - - // the JoinIdenticalVertices process has not been executed on this - // mesh, otherwise this value would normally be at least minimally - // smaller than 3.0 ... - ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum); - ASSIMP_LOG_WARN(szBuff); - return static_cast<ai_real>(0.f); - } - } - - // first we need to build a vertex-triangle adjacency list - VertexTriangleAdjacency adj(pMesh->mFaces,pMesh->mNumFaces, pMesh->mNumVertices,true); - - // build a list to store per-vertex caching time stamps - unsigned int* const piCachingStamps = new unsigned int[pMesh->mNumVertices]; - memset(piCachingStamps,0x0,pMesh->mNumVertices*sizeof(unsigned int)); - - // allocate an empty output index buffer. We store the output indices in one large array. - // Since the number of triangles won't change the input faces can be reused. This is how - // we save thousands of redundant mini allocations for aiFace::mIndices - const unsigned int iIdxCnt = pMesh->mNumFaces*3; - unsigned int* const piIBOutput = new unsigned int[iIdxCnt]; - unsigned int* piCSIter = piIBOutput; - - // allocate the flag array to hold the information - // whether a face has already been emitted or not - std::vector<bool> abEmitted(pMesh->mNumFaces,false); - - // dead-end vertex index stack - std::stack<unsigned int, std::vector<unsigned int> > sDeadEndVStack; - - // create a copy of the piNumTriPtr buffer - unsigned int* const piNumTriPtr = adj.mLiveTriangles; - const std::vector<unsigned int> piNumTriPtrNoModify(piNumTriPtr, piNumTriPtr + pMesh->mNumVertices); - - // get the largest number of referenced triangles and allocate the "candidate buffer" - unsigned int iMaxRefTris = 0; { - const unsigned int* piCur = adj.mLiveTriangles; - const unsigned int* const piCurEnd = adj.mLiveTriangles+pMesh->mNumVertices; - for (;piCur != piCurEnd;++piCur) { - iMaxRefTris = std::max(iMaxRefTris,*piCur); - } - } - ai_assert(iMaxRefTris > 0); - unsigned int* piCandidates = new unsigned int[iMaxRefTris*3]; - unsigned int iCacheMisses = 0; - - // ................................................................................... - /** PSEUDOCODE for the algorithm - - A = Build-Adjacency(I) Vertex-triangle adjacency - L = Get-Triangle-Counts(A) Per-vertex live triangle counts - C = Zero(Vertex-Count(I)) Per-vertex caching time stamps - D = Empty-Stack() Dead-end vertex stack - E = False(Triangle-Count(I)) Per triangle emitted flag - O = Empty-Index-Buffer() Empty output buffer - f = 0 Arbitrary starting vertex - s = k+1, i = 1 Time stamp and cursor - while f >= 0 For all valid fanning vertices - N = Empty-Set() 1-ring of next candidates - for each Triangle t in Neighbors(A, f) - if !Emitted(E,t) - for each Vertex v in t - Append(O,v) Output vertex - Push(D,v) Add to dead-end stack - Insert(N,v) Register as candidate - L[v] = L[v]-1 Decrease live triangle count - if s-C[v] > k If not in cache - C[v] = s Set time stamp - s = s+1 Increment time stamp - E[t] = true Flag triangle as emitted - Select next fanning vertex - f = Get-Next-Vertex(I,i,k,N,C,s,L,D) - return O - */ - // ................................................................................... - - int ivdx = 0; - int ics = 1; - int iStampCnt = mConfigCacheDepth+1; - while (ivdx >= 0) { - - unsigned int icnt = piNumTriPtrNoModify[ivdx]; - unsigned int* piList = adj.GetAdjacentTriangles(ivdx); - unsigned int* piCurCandidate = piCandidates; - - // get all triangles in the neighborhood - for (unsigned int tri = 0; tri < icnt;++tri) { - - // if they have not yet been emitted, add them to the output IB - const unsigned int fidx = *piList++; - if (!abEmitted[fidx]) { - - // so iterate through all vertices of the current triangle - const aiFace* pcFace = &pMesh->mFaces[ fidx ]; - unsigned nind = pcFace->mNumIndices; - for (unsigned ind = 0; ind < nind; ind++) { - unsigned dp = pcFace->mIndices[ind]; - - // the current vertex won't have any free triangles after this step - if (ivdx != (int)dp) { - // append the vertex to the dead-end stack - sDeadEndVStack.push(dp); - - // register as candidate for the next step - *piCurCandidate++ = dp; - - // decrease the per-vertex triangle counts - piNumTriPtr[dp]--; - } - - // append the vertex to the output index buffer - *piCSIter++ = dp; - - // if the vertex is not yet in cache, set its cache count - if (iStampCnt-piCachingStamps[dp] > mConfigCacheDepth) { - piCachingStamps[dp] = iStampCnt++; - ++iCacheMisses; - } - } - // flag triangle as emitted - abEmitted[fidx] = true; - } - } - - // the vertex has now no living adjacent triangles anymore - piNumTriPtr[ivdx] = 0; - - // get next fanning vertex - ivdx = -1; - int max_priority = -1; - for (unsigned int* piCur = piCandidates;piCur != piCurCandidate;++piCur) { - const unsigned int dp = *piCur; - - // must have live triangles - if (piNumTriPtr[dp] > 0) { - int priority = 0; - - // will the vertex be in cache, even after fanning occurs? - unsigned int tmp; - if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= mConfigCacheDepth) { - priority = tmp; - } - - // keep best candidate - if (priority > max_priority) { - max_priority = priority; - ivdx = dp; - } - } - } - // did we reach a dead end? - if (-1 == ivdx) { - // need to get a non-local vertex for which we have a good chance that it is still - // in the cache ... - while (!sDeadEndVStack.empty()) { - unsigned int iCachedIdx = sDeadEndVStack.top(); - sDeadEndVStack.pop(); - if (piNumTriPtr[ iCachedIdx ] > 0) { - ivdx = iCachedIdx; - break; - } - } - - if (-1 == ivdx) { - // well, there isn't such a vertex. Simply get the next vertex in input order and - // hope it is not too bad ... - while (ics < (int)pMesh->mNumVertices) { - ++ics; - if (piNumTriPtr[ics] > 0) { - ivdx = ics; - break; - } - } - } - } - } - ai_real fACMR2 = 0.0f; - if (!DefaultLogger::isNullLogger()) { - fACMR2 = (float)iCacheMisses / pMesh->mNumFaces; - - // very intense verbose logging ... prepare for much text if there are many meshes - if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { - ASSIMP_LOG_DEBUG_F("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f); - } - - fACMR2 *= pMesh->mNumFaces; - } - // sort the output index buffer back to the input array - piCSIter = piIBOutput; - for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace) { - unsigned nind = pcFace->mNumIndices; - unsigned * ind = pcFace->mIndices; - if (nind > 0) ind[0] = *piCSIter++; - if (nind > 1) ind[1] = *piCSIter++; - if (nind > 2) ind[2] = *piCSIter++; - } - - // delete temporary storage - delete[] piCachingStamps; - delete[] piIBOutput; - delete[] piCandidates; - - return fACMR2; -} diff --git a/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h deleted file mode 100644 index de25ecd9fb..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to reorder faces for - better cache locality*/ -#ifndef AI_IMPROVECACHELOCALITY_H_INC -#define AI_IMPROVECACHELOCALITY_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/types.h> - -struct aiMesh; - -namespace Assimp -{ - -// --------------------------------------------------------------------------- -/** The ImproveCacheLocalityProcess reorders all faces for improved vertex - * cache locality. It tries to arrange all faces to fans and to render - * faces which share vertices directly one after the other. - * - * @note This step expects triagulated input data. - */ -class ImproveCacheLocalityProcess : public BaseProcess -{ -public: - - ImproveCacheLocalityProcess(); - ~ImproveCacheLocalityProcess(); - -public: - - // ------------------------------------------------------------------- - // Check whether the pp step is active - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - // Executes the pp step on a given scene - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - // Configures the pp step - void SetupProperties(const Importer* pImp); - -protected: - // ------------------------------------------------------------------- - /** Executes the postprocessing step on the given mesh - * @param pMesh The mesh to process. - * @param meshNum Index of the mesh to process - */ - ai_real ProcessMesh( aiMesh* pMesh, unsigned int meshNum); - -private: - //! Configuration parameter: specifies the size of the cache to - //! optimize the vertex data for. - unsigned int mConfigCacheDepth; -}; - -} // end of namespace Assimp - -#endif // AI_IMPROVECACHELOCALITY_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp deleted file mode 100644 index f121fc60d3..0000000000 --- a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the post processing step to join identical vertices - * for all imported meshes - */ - - -#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS - -#include "JoinVerticesProcess.h" -#include "ProcessHelper.h" -#include <assimp/Vertex.h> -#include <assimp/TinyFormatter.h> -#include <stdio.h> -#include <unordered_set> - -using namespace Assimp; -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -JoinVerticesProcess::JoinVerticesProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -JoinVerticesProcess::~JoinVerticesProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool JoinVerticesProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_JoinIdenticalVertices) != 0; -} -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void JoinVerticesProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("JoinVerticesProcess begin"); - - // get the total number of vertices BEFORE the step is executed - int iNumOldVertices = 0; - if (!DefaultLogger::isNullLogger()) { - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { - iNumOldVertices += pScene->mMeshes[a]->mNumVertices; - } - } - - // execute the step - int iNumVertices = 0; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) - iNumVertices += ProcessMesh( pScene->mMeshes[a],a); - - // if logging is active, print detailed statistics - if (!DefaultLogger::isNullLogger()) { - if (iNumOldVertices == iNumVertices) { - ASSIMP_LOG_DEBUG("JoinVerticesProcess finished "); - } else { - ASSIMP_LOG_INFO_F("JoinVerticesProcess finished | Verts in: ", iNumOldVertices, - " out: ", iNumVertices, " | ~", - ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f ); - } - } - - pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; -} - -namespace { - -bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) -{ - // A little helper to find locally close vertices faster. - // Try to reuse the lookup table from the last step. - const static float epsilon = 1e-5f; - // Squared because we check against squared length of the vector difference - static const float squareEpsilon = epsilon * epsilon; - - // Square compare is useful for animeshes vertices compare - if ((lhs.position - rhs.position).SquareLength() > squareEpsilon) { - return false; - } - - // We just test the other attributes even if they're not present in the mesh. - // In this case they're initialized to 0 so the comparison succeeds. - // By this method the non-present attributes are effectively ignored in the comparison. - if ((lhs.normal - rhs.normal).SquareLength() > squareEpsilon) { - return false; - } - - if ((lhs.texcoords[0] - rhs.texcoords[0]).SquareLength() > squareEpsilon) { - return false; - } - - if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) { - return false; - } - - if ((lhs.bitangent - rhs.bitangent).SquareLength() > squareEpsilon) { - return false; - } - - // Usually we won't have vertex colors or multiple UVs, so we can skip from here - // Actually this increases runtime performance slightly, at least if branch - // prediction is on our side. - if (complex) { - for (int i = 0; i < 8; i++) { - if (i > 0 && (lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) { - return false; - } - if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) { - return false; - } - } - } - return true; -} - -template<class XMesh> -void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) { - // replace vertex data with the unique data sets - pMesh->mNumVertices = (unsigned int)uniqueVertices.size(); - - // ---------------------------------------------------------------------------- - // NOTE - we're *not* calling Vertex::SortBack() because it would check for - // presence of every single vertex component once PER VERTEX. And our CPU - // dislikes branches, even if they're easily predictable. - // ---------------------------------------------------------------------------- - - // Position, if present (check made for aiAnimMesh) - if (pMesh->mVertices) - { - delete [] pMesh->mVertices; - pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; - for (unsigned int a = 0; a < pMesh->mNumVertices; a++) { - pMesh->mVertices[a] = uniqueVertices[a].position; - } - } - - // Normals, if present - if (pMesh->mNormals) - { - delete [] pMesh->mNormals; - pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - for( unsigned int a = 0; a < pMesh->mNumVertices; a++) { - pMesh->mNormals[a] = uniqueVertices[a].normal; - } - } - // Tangents, if present - if (pMesh->mTangents) - { - delete [] pMesh->mTangents; - pMesh->mTangents = new aiVector3D[pMesh->mNumVertices]; - for (unsigned int a = 0; a < pMesh->mNumVertices; a++) { - pMesh->mTangents[a] = uniqueVertices[a].tangent; - } - } - // Bitangents as well - if (pMesh->mBitangents) - { - delete [] pMesh->mBitangents; - pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices]; - for (unsigned int a = 0; a < pMesh->mNumVertices; a++) { - pMesh->mBitangents[a] = uniqueVertices[a].bitangent; - } - } - // Vertex colors - for (unsigned int a = 0; pMesh->HasVertexColors(a); a++) - { - delete [] pMesh->mColors[a]; - pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices]; - for( unsigned int b = 0; b < pMesh->mNumVertices; b++) { - pMesh->mColors[a][b] = uniqueVertices[b].colors[a]; - } - } - // Texture coords - for (unsigned int a = 0; pMesh->HasTextureCoords(a); a++) - { - delete [] pMesh->mTextureCoords[a]; - pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices]; - for (unsigned int b = 0; b < pMesh->mNumVertices; b++) { - pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a]; - } - } -} -} // namespace - -// ------------------------------------------------------------------------------------------------ -// Unites identical vertices in the given mesh -int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) -{ - static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8"); - static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8"); - - // Return early if we don't have any positions - if (!pMesh->HasPositions() || !pMesh->HasFaces()) { - return 0; - } - - // We should care only about used vertices, not all of them - // (this can happen due to original file vertices buffer being used by - // multiple meshes) - std::unordered_set<unsigned int> usedVertexIndices; - usedVertexIndices.reserve(pMesh->mNumVertices); - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) - { - aiFace& face = pMesh->mFaces[a]; - for( unsigned int b = 0; b < face.mNumIndices; b++) { - usedVertexIndices.insert(face.mIndices[b]); - } - } - - // We'll never have more vertices afterwards. - std::vector<Vertex> uniqueVertices; - uniqueVertices.reserve( pMesh->mNumVertices); - - // For each vertex the index of the vertex it was replaced by. - // Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark - // whether a new vertex was created for the index (true) or if it was replaced by an existing - // unique vertex (false). This saves an additional std::vector<bool> and greatly enhances - // branching performance. - static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff"); - std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff); - - // float posEpsilonSqr; - SpatialSort* vertexFinder = NULL; - SpatialSort _vertexFinder; - - typedef std::pair<SpatialSort,float> SpatPair; - if (shared) { - std::vector<SpatPair >* avf; - shared->GetProperty(AI_SPP_SPATIAL_SORT,avf); - if (avf) { - SpatPair& blubb = (*avf)[meshIndex]; - vertexFinder = &blubb.first; - // posEpsilonSqr = blubb.second; - } - } - if (!vertexFinder) { - // bad, need to compute it. - _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D)); - vertexFinder = &_vertexFinder; - // posEpsilonSqr = ComputePositionEpsilon(pMesh); - } - - // Again, better waste some bytes than a realloc ... - std::vector<unsigned int> verticesFound; - verticesFound.reserve(10); - - // Run an optimized code path if we don't have multiple UVs or vertex colors. - // This should yield false in more than 99% of all imports ... - const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1); - const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0; - - // We'll never have more vertices afterwards. - std::vector<std::vector<Vertex>> uniqueAnimatedVertices; - if (hasAnimMeshes) { - uniqueAnimatedVertices.resize(pMesh->mNumAnimMeshes); - for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) { - uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices); - } - } - - // Now check each vertex if it brings something new to the table - for( unsigned int a = 0; a < pMesh->mNumVertices; a++) { - if (usedVertexIndices.find(a) == usedVertexIndices.end()) { - continue; - } - - // collect the vertex data - Vertex v(pMesh,a); - - // collect all vertices that are close enough to the given position - vertexFinder->FindIdenticalPositions( v.position, verticesFound); - unsigned int matchIndex = 0xffffffff; - - // check all unique vertices close to the position if this vertex is already present among them - for( unsigned int b = 0; b < verticesFound.size(); b++) { - const unsigned int vidx = verticesFound[b]; - const unsigned int uidx = replaceIndex[ vidx]; - if( uidx & 0x80000000) - continue; - - const Vertex& uv = uniqueVertices[ uidx]; - - if (!areVerticesEqual(v, uv, complex)) { - continue; - } - - if (hasAnimMeshes) { - // If given vertex is animated, then it has to be preserver 1 to 1 (base mesh and animated mesh require same topology) - // NOTE: not doing this totaly breaks anim meshes as they don't have their own faces (they use pMesh->mFaces) - bool breaksAnimMesh = false; - for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) { - const Vertex& animatedUV = uniqueAnimatedVertices[animMeshIndex][ uidx]; - Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a); - if (!areVerticesEqual(aniMeshVertex, animatedUV, complex)) { - breaksAnimMesh = true; - break; - } - } - if (breaksAnimMesh) { - continue; - } - } - - // we're still here -> this vertex perfectly matches our given vertex - matchIndex = uidx; - break; - } - - // found a replacement vertex among the uniques? - if( matchIndex != 0xffffffff) - { - // store where to found the matching unique vertex - replaceIndex[a] = matchIndex | 0x80000000; - } - else - { - // no unique vertex matches it up to now -> so add it - replaceIndex[a] = (unsigned int)uniqueVertices.size(); - uniqueVertices.push_back( v); - if (hasAnimMeshes) { - for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) { - Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a); - uniqueAnimatedVertices[animMeshIndex].push_back(aniMeshVertex); - } - } - } - } - - if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { - ASSIMP_LOG_DEBUG_F( - "Mesh ",meshIndex, - " (", - (pMesh->mName.length ? pMesh->mName.data : "unnamed"), - ") | Verts in: ",pMesh->mNumVertices, - " out: ", - uniqueVertices.size(), - " | ~", - ((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f, - "%" - ); - } - - updateXMeshVertices(pMesh, uniqueVertices); - if (hasAnimMeshes) { - for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) { - updateXMeshVertices(pMesh->mAnimMeshes[animMeshIndex], uniqueAnimatedVertices[animMeshIndex]); - } - } - - // adjust the indices in all faces - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) - { - aiFace& face = pMesh->mFaces[a]; - for( unsigned int b = 0; b < face.mNumIndices; b++) { - face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~0x80000000; - } - } - - // adjust bone vertex weights. - for( int a = 0; a < (int)pMesh->mNumBones; a++) { - aiBone* bone = pMesh->mBones[a]; - std::vector<aiVertexWeight> newWeights; - newWeights.reserve( bone->mNumWeights); - - if ( NULL != bone->mWeights ) { - for ( unsigned int b = 0; b < bone->mNumWeights; b++ ) { - const aiVertexWeight& ow = bone->mWeights[ b ]; - // if the vertex is a unique one, translate it - if ( !( replaceIndex[ ow.mVertexId ] & 0x80000000 ) ) { - aiVertexWeight nw; - nw.mVertexId = replaceIndex[ ow.mVertexId ]; - nw.mWeight = ow.mWeight; - newWeights.push_back( nw ); - } - } - } else { - ASSIMP_LOG_ERROR( "X-Export: aiBone shall contain weights, but pointer to them is NULL." ); - } - - if (newWeights.size() > 0) { - // kill the old and replace them with the translated weights - delete [] bone->mWeights; - bone->mNumWeights = (unsigned int)newWeights.size(); - - bone->mWeights = new aiVertexWeight[bone->mNumWeights]; - memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight)); - } - } - return pMesh->mNumVertices; -} - -#endif // !! ASSIMP_BUILD_NO_JOINVERTICES_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h deleted file mode 100644 index e017ae62db..0000000000 --- a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to join identical vertices - on all imported meshes.*/ -#ifndef AI_JOINVERTICESPROCESS_H_INC -#define AI_JOINVERTICESPROCESS_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/types.h> - -struct aiMesh; - -namespace Assimp -{ - -// --------------------------------------------------------------------------- -/** The JoinVerticesProcess unites identical vertices in all imported meshes. - * By default the importer returns meshes where each face addressed its own - * set of vertices even if that means that identical vertices are stored multiple - * times. The JoinVerticesProcess finds these identical vertices and - * erases all but one of the copies. This usually reduces the number of vertices - * in a mesh by a serious amount and is the standard form to render a mesh. - */ -class ASSIMP_API JoinVerticesProcess : public BaseProcess { -public: - JoinVerticesProcess(); - ~JoinVerticesProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - /** Unites identical vertices in the given mesh. - * @param pMesh The mesh to process. - * @param meshIndex Index of the mesh to process - */ - int ProcessMesh( aiMesh* pMesh, unsigned int meshIndex); -}; - -} // end of namespace Assimp - -#endif // AI_CALCTANGENTSPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp deleted file mode 100644 index d560f19287..0000000000 --- a/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** Implementation of the LimitBoneWeightsProcess post processing step */ - - -#include "LimitBoneWeightsProcess.h" -#include <assimp/StringUtils.h> -#include <assimp/postprocess.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/scene.h> -#include <stdio.h> - -using namespace Assimp; - - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -LimitBoneWeightsProcess::LimitBoneWeightsProcess() -{ - mMaxWeights = AI_LMW_MAX_WEIGHTS; -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -LimitBoneWeightsProcess::~LimitBoneWeightsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_LimitBoneWeights) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void LimitBoneWeightsProcess::Execute( aiScene* pScene) { - ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin"); - for (unsigned int a = 0; a < pScene->mNumMeshes; ++a ) { - ProcessMesh(pScene->mMeshes[a]); - } - - ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess end"); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) -{ - // get the current value of the property - this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS); -} - -// ------------------------------------------------------------------------------------------------ -// Unites identical vertices in the given mesh -void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh) -{ - if( !pMesh->HasBones()) - return; - - // collect all bone weights per vertex - typedef std::vector< std::vector< Weight > > WeightsPerVertex; - WeightsPerVertex vertexWeights( pMesh->mNumVertices); - - // collect all weights per vertex - for( unsigned int a = 0; a < pMesh->mNumBones; a++) - { - const aiBone* bone = pMesh->mBones[a]; - for( unsigned int b = 0; b < bone->mNumWeights; b++) - { - const aiVertexWeight& w = bone->mWeights[b]; - vertexWeights[w.mVertexId].push_back( Weight( a, w.mWeight)); - } - } - - unsigned int removed = 0, old_bones = pMesh->mNumBones; - - // now cut the weight count if it exceeds the maximum - bool bChanged = false; - for( WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit) - { - if( vit->size() <= mMaxWeights) - continue; - - bChanged = true; - - // more than the defined maximum -> first sort by weight in descending order. That's - // why we defined the < operator in such a weird way. - std::sort( vit->begin(), vit->end()); - - // now kill everything beyond the maximum count - unsigned int m = static_cast<unsigned int>(vit->size()); - vit->erase( vit->begin() + mMaxWeights, vit->end()); - removed += static_cast<unsigned int>(m-vit->size()); - - // and renormalize the weights - float sum = 0.0f; - for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it ) { - sum += it->mWeight; - } - if( 0.0f != sum ) { - const float invSum = 1.0f / sum; - for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it ) { - it->mWeight *= invSum; - } - } - } - - if (bChanged) { - // rebuild the vertex weight array for all bones - typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone; - WeightsPerBone boneWeights( pMesh->mNumBones); - for( unsigned int a = 0; a < vertexWeights.size(); a++) - { - const std::vector<Weight>& vw = vertexWeights[a]; - for( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it) - boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight)); - } - - // and finally copy the vertex weight list over to the mesh's bones - std::vector<bool> abNoNeed(pMesh->mNumBones,false); - bChanged = false; - - for( unsigned int a = 0; a < pMesh->mNumBones; a++) - { - const std::vector<aiVertexWeight>& bw = boneWeights[a]; - aiBone* bone = pMesh->mBones[a]; - - if ( bw.empty() ) - { - abNoNeed[a] = bChanged = true; - continue; - } - - // copy the weight list. should always be less weights than before, so we don't need a new allocation - ai_assert( bw.size() <= bone->mNumWeights); - bone->mNumWeights = static_cast<unsigned int>( bw.size() ); - ::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight)); - } - - if (bChanged) { - // the number of new bones is smaller than before, so we can reuse the old array - aiBone** ppcCur = pMesh->mBones;aiBone** ppcSrc = ppcCur; - - for (std::vector<bool>::const_iterator iter = abNoNeed.begin();iter != abNoNeed.end() ;++iter) { - if (*iter) { - delete *ppcSrc; - --pMesh->mNumBones; - } - else *ppcCur++ = *ppcSrc; - ++ppcSrc; - } - } - - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones ); - } - } -} diff --git a/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h deleted file mode 100644 index 73c2a68d53..0000000000 --- a/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** Defines a post processing step to limit the number of bones affecting a single vertex. */ -#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC -#define AI_LIMITBONEWEIGHTSPROCESS_H_INC - -#include "Common/BaseProcess.h" - -// Forward declarations -struct aiMesh; - -class LimitBoneWeightsTest; - -namespace Assimp { - -// NOTE: If you change these limits, don't forget to change the -// corresponding values in all Assimp ports - -// ********************************************************** -// Java: ConfigProperty.java, -// ConfigProperty.DEFAULT_BONE_WEIGHT_LIMIT -// ********************************************************** - -#if (!defined AI_LMW_MAX_WEIGHTS) -# define AI_LMW_MAX_WEIGHTS 0x4 -#endif // !! AI_LMW_MAX_WEIGHTS - -// --------------------------------------------------------------------------- -/** This post processing step limits the number of bones affecting a vertex -* to a certain maximum value. If a vertex is affected by more than that number -* of bones, the bone weight with the least influence on this vertex are removed. -* The other weights on this bone are then renormalized to assure the sum weight -* to be 1. -*/ -class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess { -public: - LimitBoneWeightsProcess(); - ~LimitBoneWeightsProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. - * A bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** Limits the bone weight count for all vertices in the given mesh. - * @param pMesh The mesh to process. - */ - void ProcessMesh( aiMesh* pMesh); - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - /** Describes a bone weight on a vertex */ - struct Weight { - unsigned int mBone; ///< Index of the bone - float mWeight; ///< Weight of that bone on this vertex - Weight() AI_NO_EXCEPT - : mBone(0) - , mWeight(0.0f) { - // empty - } - - Weight( unsigned int pBone, float pWeight) - : mBone(pBone) - , mWeight(pWeight) { - // empty - } - - /** Comparison operator to sort bone weights by descending weight */ - bool operator < (const Weight& pWeight) const { - return mWeight > pWeight.mWeight; - } - }; - - /** Maximum number of bones influencing any single vertex. */ - unsigned int mMaxWeights; -}; - -} // end of namespace Assimp - -#endif // AI_LIMITBONEWEIGHTSPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp deleted file mode 100644 index 41f50a5ba5..0000000000 --- a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file Implementation of the post processing step "MakeVerboseFormat" -*/ - - -#include "MakeVerboseFormat.h" -#include <assimp/scene.h> -#include <assimp/DefaultLogger.hpp> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -MakeVerboseFormatProcess::MakeVerboseFormatProcess() -{ - // nothing to do here -} -// ------------------------------------------------------------------------------------------------ -MakeVerboseFormatProcess::~MakeVerboseFormatProcess() -{ - // nothing to do here -} -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void MakeVerboseFormatProcess::Execute( aiScene* pScene) -{ - ai_assert(NULL != pScene); - ASSIMP_LOG_DEBUG("MakeVerboseFormatProcess begin"); - - bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) - { - if( MakeVerboseFormat( pScene->mMeshes[a])) - bHas = true; - } - if (bHas) { - ASSIMP_LOG_INFO("MakeVerboseFormatProcess finished. There was much work to do ..."); - } else { - ASSIMP_LOG_DEBUG("MakeVerboseFormatProcess. There was nothing to do."); - } - - pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh) -{ - ai_assert(NULL != pcMesh); - - unsigned int iOldNumVertices = pcMesh->mNumVertices; - const unsigned int iNumVerts = pcMesh->mNumFaces*3; - - aiVector3D* pvPositions = new aiVector3D[ iNumVerts ]; - - aiVector3D* pvNormals = NULL; - if (pcMesh->HasNormals()) - { - pvNormals = new aiVector3D[iNumVerts]; - } - aiVector3D* pvTangents = NULL, *pvBitangents = NULL; - if (pcMesh->HasTangentsAndBitangents()) - { - pvTangents = new aiVector3D[iNumVerts]; - pvBitangents = new aiVector3D[iNumVerts]; - } - - aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {0}; - aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {0}; - - unsigned int p = 0; - while (pcMesh->HasTextureCoords(p)) - apvTextureCoords[p++] = new aiVector3D[iNumVerts]; - - p = 0; - while (pcMesh->HasVertexColors(p)) - apvColorSets[p++] = new aiColor4D[iNumVerts]; - - // allocate enough memory to hold output bones and vertex weights ... - std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones]; - for (unsigned int i = 0;i < pcMesh->mNumBones;++i) { - newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3); - } - - // iterate through all faces and build a clean list - unsigned int iIndex = 0; - for (unsigned int a = 0; a< pcMesh->mNumFaces;++a) - { - aiFace* pcFace = &pcMesh->mFaces[a]; - for (unsigned int q = 0; q < pcFace->mNumIndices;++q,++iIndex) - { - // need to build a clean list of bones, too - for (unsigned int i = 0;i < pcMesh->mNumBones;++i) - { - for (unsigned int a = 0; a < pcMesh->mBones[i]->mNumWeights;a++) - { - const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a]; - if(pcFace->mIndices[q] == w.mVertexId) - { - aiVertexWeight wNew; - wNew.mVertexId = iIndex; - wNew.mWeight = w.mWeight; - newWeights[i].push_back(wNew); - } - } - } - - pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]]; - - if (pcMesh->HasNormals()) - { - pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]]; - } - if (pcMesh->HasTangentsAndBitangents()) - { - pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]]; - pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]]; - } - - unsigned int p = 0; - while (pcMesh->HasTextureCoords(p)) - { - apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]]; - ++p; - } - p = 0; - while (pcMesh->HasVertexColors(p)) - { - apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]]; - ++p; - } - pcFace->mIndices[q] = iIndex; - } - } - - - - // build output vertex weights - for (unsigned int i = 0;i < pcMesh->mNumBones;++i) - { - delete [] pcMesh->mBones[i]->mWeights; - if (!newWeights[i].empty()) { - pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()]; - aiVertexWeight *weightToCopy = &( newWeights[i][0] ); - memcpy(pcMesh->mBones[i]->mWeights, weightToCopy, - sizeof(aiVertexWeight) * newWeights[i].size()); - } else { - pcMesh->mBones[i]->mWeights = NULL; - } - } - delete[] newWeights; - - // delete the old members - delete[] pcMesh->mVertices; - pcMesh->mVertices = pvPositions; - - p = 0; - while (pcMesh->HasTextureCoords(p)) - { - delete[] pcMesh->mTextureCoords[p]; - pcMesh->mTextureCoords[p] = apvTextureCoords[p]; - ++p; - } - p = 0; - while (pcMesh->HasVertexColors(p)) - { - delete[] pcMesh->mColors[p]; - pcMesh->mColors[p] = apvColorSets[p]; - ++p; - } - pcMesh->mNumVertices = iNumVerts; - - if (pcMesh->HasNormals()) - { - delete[] pcMesh->mNormals; - pcMesh->mNormals = pvNormals; - } - if (pcMesh->HasTangentsAndBitangents()) - { - delete[] pcMesh->mTangents; - pcMesh->mTangents = pvTangents; - delete[] pcMesh->mBitangents; - pcMesh->mBitangents = pvBitangents; - } - return (pcMesh->mNumVertices != iOldNumVertices); -} - - -// ------------------------------------------------------------------------------------------------ -bool IsMeshInVerboseFormat(const aiMesh* mesh) { - // avoid slow vector<bool> specialization - std::vector<unsigned int> seen(mesh->mNumVertices,0); - for(unsigned int i = 0; i < mesh->mNumFaces; ++i) { - const aiFace& f = mesh->mFaces[i]; - for(unsigned int j = 0; j < f.mNumIndices; ++j) { - if(++seen[f.mIndices[j]] == 2) { - // found a duplicate index - return false; - } - } - } - - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) { - for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) { - return false; - } - } - - return true; -} diff --git a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h deleted file mode 100644 index 8565d5933a..0000000000 --- a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to bring a given scene - into the verbose format that is expected by most postprocess steps. - This is the inverse of the "JoinIdenticalVertices" step. */ -#ifndef AI_MAKEVERBOSEFORMAT_H_INC -#define AI_MAKEVERBOSEFORMAT_H_INC - -#include "Common/BaseProcess.h" - -struct aiMesh; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** MakeVerboseFormatProcess: Class to convert an asset to the verbose - * format which is expected by most postprocess steps. - * - * This is the inverse of what the "JoinIdenticalVertices" step is doing. - * This step has no official flag (since it wouldn't make sense to run it - * during import). It is intended for applications intending to modify the - * returned aiScene. After this step has been executed, they can execute - * other postprocess steps on the data. The code might also be useful to - * quickly adapt code that doesn't result in a verbose representation of - * the scene data. - * The step has been added because it was required by the viewer, however - * it has been moved to the main library since others might find it - * useful, too. */ -class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess -{ -public: - - - MakeVerboseFormatProcess(); - ~MakeVerboseFormatProcess(); - -public: - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not */ - bool IsActive( unsigned int /*pFlags*/ ) const - { - // NOTE: There is no direct flag that corresponds to - // this postprocess step. - return false; - } - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. */ - void Execute( aiScene* pScene); - -public: - - // ------------------------------------------------------------------- - /** Checks whether the scene is already in verbose format. - * @param pScene The data to check. - * @return true if the scene is already in verbose format. */ - static bool IsVerboseFormat(const aiScene* pScene); - -private: - - //! Apply the postprocess step to a given submesh - bool MakeVerboseFormat (aiMesh* pcMesh); -}; - -} // end of namespace Assimp - -#endif // !!AI_KILLNORMALPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp deleted file mode 100644 index 5db51f58b6..0000000000 --- a/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file OptimizeGraph.cpp - * @brief Implementation of the aiProcess_OptimizGraph step - */ - - -#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS - -#include "OptimizeGraph.h" -#include "ProcessHelper.h" -#include <assimp/SceneCombiner.h> -#include <assimp/Exceptional.h> -#include <stdio.h> - -using namespace Assimp; - -#define AI_RESERVED_NODE_NAME "$Reserved_And_Evil" - -/* AI_OG_USE_HASHING enables the use of hashing to speed-up std::set lookups. - * The unhashed variant should be faster, except for *very* large data sets - */ -#ifdef AI_OG_USE_HASHING - // Use our standard hashing function to compute the hash -# define AI_OG_GETKEY(str) SuperFastHash(str.data,str.length) -#else - // Otherwise hope that std::string will utilize a static buffer - // for shorter node names. This would avoid endless heap copying. -# define AI_OG_GETKEY(str) std::string(str.data) -#endif - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -OptimizeGraphProcess::OptimizeGraphProcess() -: mScene() -, nodes_in() -, nodes_out() -, count_merged() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -OptimizeGraphProcess::~OptimizeGraphProcess() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool OptimizeGraphProcess::IsActive( unsigned int pFlags) const { - return (0 != (pFlags & aiProcess_OptimizeGraph)); -} - -// ------------------------------------------------------------------------------------------------ -// Setup properties for the post-processing step -void OptimizeGraphProcess::SetupProperties(const Importer* pImp) { - // Get value of AI_CONFIG_PP_OG_EXCLUDE_LIST - std::string tmp = pImp->GetPropertyString(AI_CONFIG_PP_OG_EXCLUDE_LIST,""); - AddLockedNodeList(tmp); -} - -// ------------------------------------------------------------------------------------------------ -// Collect new children -void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes) { - nodes_in += nd->mNumChildren; - - // Process children - std::list<aiNode*> child_nodes; - for (unsigned int i = 0; i < nd->mNumChildren; ++i) { - CollectNewChildren(nd->mChildren[i],child_nodes); - nd->mChildren[i] = nullptr; - } - - // Check whether we need this node; if not we can replace it by our own children (warn, danger of incest). - if (locked.find(AI_OG_GETKEY(nd->mName)) == locked.end() ) { - for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) { - - if (locked.find(AI_OG_GETKEY((*it)->mName)) == locked.end()) { - (*it)->mTransformation = nd->mTransformation * (*it)->mTransformation; - nodes.push_back(*it); - - it = child_nodes.erase(it); - continue; - } - ++it; - } - - if (nd->mNumMeshes || !child_nodes.empty()) { - nodes.push_back(nd); - } else { - delete nd; /* bye, node */ - return; - } - } else { - - // Retain our current position in the hierarchy - nodes.push_back(nd); - - // Now check for possible optimizations in our list of child nodes. join as many as possible - aiNode* join_master = NULL; - aiMatrix4x4 inv; - - const LockedSetType::const_iterator end = locked.end(); - - std::list<aiNode*> join; - for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) { - aiNode* child = *it; - if (child->mNumChildren == 0 && locked.find(AI_OG_GETKEY(child->mName)) == end) { - - // There may be no instanced meshes - unsigned int n = 0; - for (; n < child->mNumMeshes;++n) { - if (meshes[child->mMeshes[n]] > 1) { - break; - } - } - if (n == child->mNumMeshes) { - if (!join_master) { - join_master = child; - inv = join_master->mTransformation; - inv.Inverse(); - } else { - child->mTransformation = inv * child->mTransformation ; - - join.push_back(child); - it = child_nodes.erase(it); - continue; - } - } - } - ++it; - } - if (join_master && !join.empty()) { - join_master->mName.length = ::ai_snprintf(join_master->mName.data, MAXLEN, "$MergedNode_%i",count_merged++); - - unsigned int out_meshes = 0; - for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) { - out_meshes += (*it)->mNumMeshes; - } - - // copy all mesh references in one array - if (out_meshes) { - unsigned int* meshes = new unsigned int[out_meshes+join_master->mNumMeshes], *tmp = meshes; - for (unsigned int n = 0; n < join_master->mNumMeshes;++n) { - *tmp++ = join_master->mMeshes[n]; - } - - for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) { - for (unsigned int n = 0; n < (*it)->mNumMeshes; ++n) { - - *tmp = (*it)->mMeshes[n]; - aiMesh* mesh = mScene->mMeshes[*tmp++]; - - // manually move the mesh into the right coordinate system - const aiMatrix3x3 IT = aiMatrix3x3( (*it)->mTransformation ).Inverse().Transpose(); - for (unsigned int a = 0; a < mesh->mNumVertices; ++a) { - - mesh->mVertices[a] *= (*it)->mTransformation; - - if (mesh->HasNormals()) - mesh->mNormals[a] *= IT; - - if (mesh->HasTangentsAndBitangents()) { - mesh->mTangents[a] *= IT; - mesh->mBitangents[a] *= IT; - } - } - } - delete *it; // bye, node - } - delete[] join_master->mMeshes; - join_master->mMeshes = meshes; - join_master->mNumMeshes += out_meshes; - } - } - } - // reassign children if something changed - if (child_nodes.empty() || child_nodes.size() > nd->mNumChildren) { - - delete[] nd->mChildren; - - if (!child_nodes.empty()) { - nd->mChildren = new aiNode*[child_nodes.size()]; - } - else nd->mChildren = nullptr; - } - - nd->mNumChildren = static_cast<unsigned int>(child_nodes.size()); - - if (nd->mChildren) { - aiNode** tmp = nd->mChildren; - for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) { - aiNode* node = *tmp++ = *it; - node->mParent = nd; - } - } - - nodes_out += static_cast<unsigned int>(child_nodes.size()); -} - -// ------------------------------------------------------------------------------------------------ -// Execute the post-processing step on the given scene -void OptimizeGraphProcess::Execute( aiScene* pScene) { - ASSIMP_LOG_DEBUG("OptimizeGraphProcess begin"); - nodes_in = nodes_out = count_merged = 0; - mScene = pScene; - - meshes.resize(pScene->mNumMeshes,0); - FindInstancedMeshes(pScene->mRootNode); - - // build a blacklist of identifiers. If the name of a node matches one of these, we won't touch it - locked.clear(); - for (std::list<std::string>::const_iterator it = locked_nodes.begin(); it != locked_nodes.end(); ++it) { -#ifdef AI_OG_USE_HASHING - locked.insert(SuperFastHash((*it).c_str())); -#else - locked.insert(*it); -#endif - } - - for (unsigned int i = 0; i < pScene->mNumAnimations; ++i) { - for (unsigned int a = 0; a < pScene->mAnimations[i]->mNumChannels; ++a) { - aiNodeAnim* anim = pScene->mAnimations[i]->mChannels[a]; - locked.insert(AI_OG_GETKEY(anim->mNodeName)); - } - } - - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - for (unsigned int a = 0; a < pScene->mMeshes[i]->mNumBones; ++a) { - - aiBone* bone = pScene->mMeshes[i]->mBones[a]; - locked.insert(AI_OG_GETKEY(bone->mName)); - - // HACK: Meshes referencing bones may not be transformed; we need to look them. - // The easiest way to do this is to increase their reference counters ... - meshes[i] += 2; - } - } - - for (unsigned int i = 0; i < pScene->mNumCameras; ++i) { - aiCamera* cam = pScene->mCameras[i]; - locked.insert(AI_OG_GETKEY(cam->mName)); - } - - for (unsigned int i = 0; i < pScene->mNumLights; ++i) { - aiLight* lgh = pScene->mLights[i]; - locked.insert(AI_OG_GETKEY(lgh->mName)); - } - - // Insert a dummy master node and make it read-only - aiNode* dummy_root = new aiNode(AI_RESERVED_NODE_NAME); - locked.insert(AI_OG_GETKEY(dummy_root->mName)); - - const aiString prev = pScene->mRootNode->mName; - pScene->mRootNode->mParent = dummy_root; - - dummy_root->mChildren = new aiNode*[dummy_root->mNumChildren = 1]; - dummy_root->mChildren[0] = pScene->mRootNode; - - // Do our recursive processing of scenegraph nodes. For each node collect - // a fully new list of children and allow their children to place themselves - // on the same hierarchy layer as their parents. - std::list<aiNode*> nodes; - CollectNewChildren (dummy_root,nodes); - - ai_assert(nodes.size() == 1); - - if (dummy_root->mNumChildren == 0) { - pScene->mRootNode = NULL; - throw DeadlyImportError("After optimizing the scene graph, no data remains"); - } - - if (dummy_root->mNumChildren > 1) { - pScene->mRootNode = dummy_root; - - // Keep the dummy node but assign the name of the old root node to it - pScene->mRootNode->mName = prev; - } - else { - - // Remove the dummy root node again. - pScene->mRootNode = dummy_root->mChildren[0]; - - dummy_root->mChildren[0] = NULL; - delete dummy_root; - } - - pScene->mRootNode->mParent = NULL; - if (!DefaultLogger::isNullLogger()) { - if ( nodes_in != nodes_out) { - ASSIMP_LOG_INFO_F("OptimizeGraphProcess finished; Input nodes: ", nodes_in, ", Output nodes: ", nodes_out); - } else { - ASSIMP_LOG_DEBUG("OptimizeGraphProcess finished"); - } - } - meshes.clear(); - locked.clear(); -} - -// ------------------------------------------------------------------------------------------------ -// Build a LUT of all instanced meshes -void OptimizeGraphProcess::FindInstancedMeshes (aiNode* pNode) -{ - for (unsigned int i = 0; i < pNode->mNumMeshes;++i) { - ++meshes[pNode->mMeshes[i]]; - } - - for (unsigned int i = 0; i < pNode->mNumChildren; ++i) - FindInstancedMeshes(pNode->mChildren[i]); -} - -#endif // !! ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h deleted file mode 100644 index 82cc5db3fe..0000000000 --- a/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file OptimizeGraph.h - * @brief Declares a post processing step to optimize the scenegraph - */ -#ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC -#define AI_OPTIMIZEGRAPHPROCESS_H_INC - -#include "Common/BaseProcess.h" -#include "PostProcessing/ProcessHelper.h" - -#include <assimp/types.h> - -#include <set> - -// Forward declarations -struct aiMesh; - -class OptimizeGraphProcessTest; - -namespace Assimp { - -// ----------------------------------------------------------------------------- -/** @brief Postprocessing step to optimize the scenegraph - * - * The implementation tries to merge nodes, even if they use different - * transformations. Animations are preserved. - * - * @see aiProcess_OptimizeGraph for a detailed description of the - * algorithm being applied. - */ -class OptimizeGraphProcess : public BaseProcess { -public: - OptimizeGraphProcess(); - ~OptimizeGraphProcess(); - - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** @brief Add a list of node names to be locked and not modified. - * @param in List of nodes. See #AI_CONFIG_PP_OG_EXCLUDE_LIST for - * format explanations. - */ - inline void AddLockedNodeList(std::string& in) { - ConvertListToStrings (in,locked_nodes); - } - - // ------------------------------------------------------------------- - /** @brief Add another node to be locked and not modified. - * @param name Name to be locked - */ - inline void AddLockedNode(std::string& name) { - locked_nodes.push_back(name); - } - - // ------------------------------------------------------------------- - /** @brief Remove a node from the list of locked nodes. - * @param name Name to be unlocked - */ - inline void RemoveLockedNode(std::string& name) { - locked_nodes.remove(name); - } - -protected: - void CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes); - void FindInstancedMeshes (aiNode* pNode); - -private: -#ifdef AI_OG_USE_HASHING - typedef std::set<unsigned int> LockedSetType; -#else - typedef std::set<std::string> LockedSetType; -#endif - - //! Scene we're working with - aiScene* mScene; - - //! List of locked names. Stored is the hash of the name - LockedSetType locked; - - //! List of nodes to be locked in addition to those with animations, lights or cameras assigned. - std::list<std::string> locked_nodes; - - //! Node counters for logging purposes - unsigned int nodes_in,nodes_out, count_merged; - - //! Reference counters for meshes - std::vector<unsigned int> meshes; -}; - -} // end of namespace Assimp - -#endif // AI_OPTIMIZEGRAPHPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp deleted file mode 100644 index 3f6765f6ca..0000000000 --- a/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file OptimizeMeshes.cpp - * @brief Implementation of the aiProcess_OptimizeMeshes step - */ - - -#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS - - -#include "OptimizeMeshes.h" -#include "ProcessHelper.h" -#include <assimp/SceneCombiner.h> -#include <assimp/Exceptional.h> - -using namespace Assimp; - -static const unsigned int NotSet = 0xffffffff; -static const unsigned int DeadBeef = 0xdeadbeef; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -OptimizeMeshesProcess::OptimizeMeshesProcess() - : mScene() - , pts(false) - , max_verts( NotSet ) - , max_faces( NotSet ) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -OptimizeMeshesProcess::~OptimizeMeshesProcess() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const -{ - // Our behaviour needs to be different if the SortByPType or SplitLargeMeshes - // steps are active. Thus we need to query their flags here and store the - // information, although we're breaking const-correctness. - // That's a serious design flaw, consider redesign. - if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) { - pts = (0 != (pFlags & aiProcess_SortByPType)); - max_verts = ( 0 != ( pFlags & aiProcess_SplitLargeMeshes ) ) ? DeadBeef : max_verts; - return true; - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Setup properties for the post-processing step -void OptimizeMeshesProcess::SetupProperties(const Importer* pImp) -{ - if( max_verts == DeadBeef /* magic hack */ ) { - max_faces = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES); - max_verts = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES); - } -} - -// ------------------------------------------------------------------------------------------------ -// Execute step -void OptimizeMeshesProcess::Execute( aiScene* pScene) -{ - const unsigned int num_old = pScene->mNumMeshes; - if (num_old <= 1) { - ASSIMP_LOG_DEBUG("Skipping OptimizeMeshesProcess"); - return; - } - - ASSIMP_LOG_DEBUG("OptimizeMeshesProcess begin"); - mScene = pScene; - - // need to clear persistent members from previous runs - merge_list.resize( 0 ); - output.resize( 0 ); - - // ensure we have the right sizes - merge_list.reserve(pScene->mNumMeshes); - output.reserve(pScene->mNumMeshes); - - // Prepare lookup tables - meshes.resize(pScene->mNumMeshes); - FindInstancedMeshes(pScene->mRootNode); - if( max_verts == DeadBeef ) /* undo the magic hack */ - max_verts = NotSet; - - // ... instanced meshes are immediately processed and added to the output list - for (unsigned int i = 0, n = 0; i < pScene->mNumMeshes;++i) { - meshes[i].vertex_format = GetMeshVFormatUnique(pScene->mMeshes[i]); - - if (meshes[i].instance_cnt > 1 && meshes[i].output_id == NotSet ) { - meshes[i].output_id = n++; - output.push_back(mScene->mMeshes[i]); - } - } - - // and process all nodes in the scenegraph recursively - ProcessNode(pScene->mRootNode); - if (!output.size()) { - throw DeadlyImportError("OptimizeMeshes: No meshes remaining; there's definitely something wrong"); - } - - meshes.resize( 0 ); - ai_assert(output.size() <= num_old); - - mScene->mNumMeshes = static_cast<unsigned int>(output.size()); - std::copy(output.begin(),output.end(),mScene->mMeshes); - - if (output.size() != num_old) { - ASSIMP_LOG_DEBUG_F("OptimizeMeshesProcess finished. Input meshes: ", num_old, ", Output meshes: ", pScene->mNumMeshes); - } else { - ASSIMP_LOG_DEBUG( "OptimizeMeshesProcess finished" ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Process meshes for a single node -void OptimizeMeshesProcess::ProcessNode( aiNode* pNode) -{ - for (unsigned int i = 0; i < pNode->mNumMeshes;++i) { - unsigned int& im = pNode->mMeshes[i]; - - if (meshes[im].instance_cnt > 1) { - im = meshes[im].output_id; - } - else { - merge_list.resize( 0 ); - unsigned int verts = 0, faces = 0; - - // Find meshes to merge with us - for (unsigned int a = i+1; a < pNode->mNumMeshes;++a) { - unsigned int am = pNode->mMeshes[a]; - if (meshes[am].instance_cnt == 1 && CanJoin(im,am,verts,faces)) { - - merge_list.push_back(mScene->mMeshes[am]); - verts += mScene->mMeshes[am]->mNumVertices; - faces += mScene->mMeshes[am]->mNumFaces; - - pNode->mMeshes[a] = pNode->mMeshes[pNode->mNumMeshes - 1]; - --pNode->mNumMeshes; - --a; - } - } - - // and merge all meshes which we found, replace the old ones - if (!merge_list.empty()) { - merge_list.push_back(mScene->mMeshes[im]); - - aiMesh* out; - SceneCombiner::MergeMeshes(&out,0,merge_list.begin(),merge_list.end()); - output.push_back(out); - } else { - output.push_back(mScene->mMeshes[im]); - } - im = static_cast<unsigned int>(output.size()-1); - } - } - - - for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) { - ProcessNode( pNode->mChildren[ i ] ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Check whether two meshes can be joined -bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned int verts, unsigned int faces ) -{ - if (meshes[a].vertex_format != meshes[b].vertex_format) - return false; - - aiMesh* ma = mScene->mMeshes[a], *mb = mScene->mMeshes[b]; - - if ((NotSet != max_verts && verts+mb->mNumVertices > max_verts) || - (NotSet != max_faces && faces+mb->mNumFaces > max_faces)) { - return false; - } - - // Never merge unskinned meshes with skinned meshes - if (ma->mMaterialIndex != mb->mMaterialIndex || ma->HasBones() != mb->HasBones()) - return false; - - // Never merge meshes with different kinds of primitives if SortByPType did already - // do its work. We would destroy everything again ... - if (pts && ma->mPrimitiveTypes != mb->mPrimitiveTypes) - return false; - - // If both meshes are skinned, check whether we have many bones defined in both meshes. - // If yes, we can join them. - if (ma->HasBones()) { - // TODO - return false; - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Build a LUT of all instanced meshes -void OptimizeMeshesProcess::FindInstancedMeshes (aiNode* pNode) -{ - for( unsigned int i = 0; i < pNode->mNumMeshes; ++i ) { - ++meshes[ pNode->mMeshes[ i ] ].instance_cnt; - } - - for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) { - FindInstancedMeshes( pNode->mChildren[ i ] ); - } -} - -// ------------------------------------------------------------------------------------------------ - -#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h deleted file mode 100644 index dec4ab52de..0000000000 --- a/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h +++ /dev/null @@ -1,186 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file OptimizeMeshes.h - * @brief Declares a post processing step to join meshes, if possible - */ -#ifndef AI_OPTIMIZEMESHESPROCESS_H_INC -#define AI_OPTIMIZEMESHESPROCESS_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/types.h> - -#include <vector> - -struct aiMesh; -struct aiNode; -class OptimizeMeshesProcessTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** @brief Postprocessing step to optimize mesh usage - * - * The implementation looks for meshes that could be joined and joins them. - * Usually this will reduce the number of drawcalls. - * - * @note Instanced meshes are currently not processed. - */ -class OptimizeMeshesProcess : public BaseProcess { -public: - /// @brief The class constructor. - OptimizeMeshesProcess(); - - /// @brief The class destructor. - ~OptimizeMeshesProcess(); - - /** @brief Internal utility to store additional mesh info - */ - struct MeshInfo { - MeshInfo() AI_NO_EXCEPT - : instance_cnt(0) - , vertex_format(0) - , output_id(0xffffffff) { - // empty - } - - //! Number of times this mesh is referenced - unsigned int instance_cnt; - - //! Vertex format id - unsigned int vertex_format; - - //! Output ID - unsigned int output_id; - }; - -public: - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - void SetupProperties(const Importer* pImp); - - - // ------------------------------------------------------------------- - /** @brief Specify whether you want meshes with different - * primitive types to be merged as well. - * - * IsActive() sets this property automatically to true if the - * aiProcess_SortByPType flag is found. - */ - void EnablePrimitiveTypeSorting(bool enable) { - pts = enable; - } - - // Getter - bool IsPrimitiveTypeSortingEnabled () const { - return pts; - } - - - // ------------------------------------------------------------------- - /** @brief Specify a maximum size of a single output mesh. - * - * If a single input mesh already exceeds this limit, it won't - * be split. - * @param verts Maximum number of vertices per mesh - * @param faces Maximum number of faces per mesh - */ - void SetPreferredMeshSizeLimit (unsigned int verts, unsigned int faces) - { - max_verts = verts; - max_faces = faces; - } - - -protected: - - // ------------------------------------------------------------------- - /** @brief Do the actual optimization on all meshes of this node - * @param pNode Node we're working with - */ - void ProcessNode( aiNode* pNode); - - // ------------------------------------------------------------------- - /** @brief Returns true if b can be joined with a - * - * @param verts Number of output verts up to now - * @param faces Number of output faces up to now - */ - bool CanJoin ( unsigned int a, unsigned int b, - unsigned int verts, unsigned int faces ); - - // ------------------------------------------------------------------- - /** @brief Find instanced meshes, for the moment we're excluding - * them from all optimizations - */ - void FindInstancedMeshes (aiNode* pNode); - -private: - - //! Scene we're working with - aiScene* mScene; - - //! Per mesh info - std::vector<MeshInfo> meshes; - - //! Output meshes - std::vector<aiMesh*> output; - - //! @see EnablePrimitiveTypeSorting - mutable bool pts; - - //! @see SetPreferredMeshSizeLimit - mutable unsigned int max_verts,max_faces; - - //! Temporary storage - std::vector<aiMesh*> merge_list; -}; - -} // end of namespace Assimp - -#endif // AI_CALCTANGENTSPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp b/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp deleted file mode 100644 index 52001a0578..0000000000 --- a/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp +++ /dev/null @@ -1,728 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file PretransformVertices.cpp - * @brief Implementation of the "PretransformVertices" post processing step -*/ - - -#include "PretransformVertices.h" -#include "ProcessHelper.h" -#include <assimp/SceneCombiner.h> -#include <assimp/Exceptional.h> - -using namespace Assimp; - -// some array offsets -#define AI_PTVS_VERTEX 0x0 -#define AI_PTVS_FACE 0x1 - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -PretransformVertices::PretransformVertices() -: configKeepHierarchy (false) -, configNormalize(false) -, configTransform(false) -, configTransformation() -, mConfigPointCloud( false ) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -PretransformVertices::~PretransformVertices() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool PretransformVertices::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_PreTransformVertices) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Setup import configuration -void PretransformVertices::SetupProperties(const Importer* pImp) -{ - // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE, - // AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION - configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0)); - configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0)); - configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION,0)); - - configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4()); - - mConfigPointCloud = pImp->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS); -} - -// ------------------------------------------------------------------------------------------------ -// Count the number of nodes -unsigned int PretransformVertices::CountNodes( aiNode* pcNode ) -{ - unsigned int iRet = 1; - for (unsigned int i = 0;i < pcNode->mNumChildren;++i) - { - iRet += CountNodes(pcNode->mChildren[i]); - } - return iRet; -} - -// ------------------------------------------------------------------------------------------------ -// Get a bitwise combination identifying the vertex format of a mesh -unsigned int PretransformVertices::GetMeshVFormat( aiMesh* pcMesh ) -{ - // the vertex format is stored in aiMesh::mBones for later retrieval. - // there isn't a good reason to compute it a few hundred times - // from scratch. The pointer is unused as animations are lost - // during PretransformVertices. - if (pcMesh->mBones) - return (unsigned int)(uint64_t)pcMesh->mBones; - - - const unsigned int iRet = GetMeshVFormatUnique(pcMesh); - - // store the value for later use - pcMesh->mBones = (aiBone**)(uint64_t)iRet; - return iRet; -} - -// ------------------------------------------------------------------------------------------------ -// Count the number of vertices in the whole scene and a given -// material index -void PretransformVertices::CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat, - unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices) -{ - for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) - { - aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; - if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh)) - { - *piVertices += pcMesh->mNumVertices; - *piFaces += pcMesh->mNumFaces; - } - } - for (unsigned int i = 0;i < pcNode->mNumChildren;++i) - { - CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat, - iVFormat,piFaces,piVertices); - } -} - -// ------------------------------------------------------------------------------------------------ -// Collect vertex/face data -void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat, - unsigned int iVFormat, aiMesh* pcMeshOut, - unsigned int aiCurrent[2], unsigned int* num_refs) -{ - // No need to multiply if there's no transformation - const bool identity = pcNode->mTransformation.IsIdentity(); - for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) - { - aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; - if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh)) - { - // Decrement mesh reference counter - unsigned int& num_ref = num_refs[pcNode->mMeshes[i]]; - ai_assert(0 != num_ref); - --num_ref; - // Save the name of the last mesh - if (num_ref==0) - { - pcMeshOut->mName = pcMesh->mName; - } - - if (identity) { - // copy positions without modifying them - ::memcpy(pcMeshOut->mVertices + aiCurrent[AI_PTVS_VERTEX], - pcMesh->mVertices, - pcMesh->mNumVertices * sizeof(aiVector3D)); - - if (iVFormat & 0x2) { - // copy normals without modifying them - ::memcpy(pcMeshOut->mNormals + aiCurrent[AI_PTVS_VERTEX], - pcMesh->mNormals, - pcMesh->mNumVertices * sizeof(aiVector3D)); - } - if (iVFormat & 0x4) - { - // copy tangents without modifying them - ::memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX], - pcMesh->mTangents, - pcMesh->mNumVertices * sizeof(aiVector3D)); - // copy bitangents without modifying them - ::memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX], - pcMesh->mBitangents, - pcMesh->mNumVertices * sizeof(aiVector3D)); - } - } - else - { - // copy positions, transform them to worldspace - for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) { - pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] = pcNode->mTransformation * pcMesh->mVertices[n]; - } - aiMatrix4x4 mWorldIT = pcNode->mTransformation; - mWorldIT.Inverse().Transpose(); - - // TODO: implement Inverse() for aiMatrix3x3 - aiMatrix3x3 m = aiMatrix3x3(mWorldIT); - - if (iVFormat & 0x2) - { - // copy normals, transform them to worldspace - for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) { - pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] = - (m * pcMesh->mNormals[n]).Normalize(); - } - } - if (iVFormat & 0x4) - { - // copy tangents and bitangents, transform them to worldspace - for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) { - pcMeshOut->mTangents [aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mTangents[n]).Normalize(); - pcMeshOut->mBitangents[aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mBitangents[n]).Normalize(); - } - } - } - unsigned int p = 0; - while (iVFormat & (0x100 << p)) - { - // copy texture coordinates - memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX], - pcMesh->mTextureCoords[p], - pcMesh->mNumVertices * sizeof(aiVector3D)); - ++p; - } - p = 0; - while (iVFormat & (0x1000000 << p)) - { - // copy vertex colors - memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX], - pcMesh->mColors[p], - pcMesh->mNumVertices * sizeof(aiColor4D)); - ++p; - } - // now we need to copy all faces. since we will delete the source mesh afterwards, - // we don't need to reallocate the array of indices except if this mesh is - // referenced multiple times. - for (unsigned int planck = 0;planck < pcMesh->mNumFaces;++planck) - { - aiFace& f_src = pcMesh->mFaces[planck]; - aiFace& f_dst = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck]; - - const unsigned int num_idx = f_src.mNumIndices; - - f_dst.mNumIndices = num_idx; - - unsigned int* pi; - if (!num_ref) { /* if last time the mesh is referenced -> no reallocation */ - pi = f_dst.mIndices = f_src.mIndices; - - // offset all vertex indices - for (unsigned int hahn = 0; hahn < num_idx;++hahn){ - pi[hahn] += aiCurrent[AI_PTVS_VERTEX]; - } - } - else { - pi = f_dst.mIndices = new unsigned int[num_idx]; - - // copy and offset all vertex indices - for (unsigned int hahn = 0; hahn < num_idx;++hahn){ - pi[hahn] = f_src.mIndices[hahn] + aiCurrent[AI_PTVS_VERTEX]; - } - } - - // Update the mPrimitiveTypes member of the mesh - switch (pcMesh->mFaces[planck].mNumIndices) - { - case 0x1: - pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - case 0x2: - pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - case 0x3: - pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - default: - pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - break; - }; - } - aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices; - aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces; - } - } - - // append all children of us - for (unsigned int i = 0;i < pcNode->mNumChildren;++i) { - CollectData(pcScene,pcNode->mChildren[i],iMat, - iVFormat,pcMeshOut,aiCurrent,num_refs); - } -} - -// ------------------------------------------------------------------------------------------------ -// Get a list of all vertex formats that occur for a given material index -// The output list contains duplicate elements -void PretransformVertices::GetVFormatList( aiScene* pcScene, unsigned int iMat, - std::list<unsigned int>& aiOut) -{ - for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) - { - aiMesh* pcMesh = pcScene->mMeshes[ i ]; - if (iMat == pcMesh->mMaterialIndex) { - aiOut.push_back(GetMeshVFormat(pcMesh)); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Compute the absolute transformation matrices of each node -void PretransformVertices::ComputeAbsoluteTransform( aiNode* pcNode ) -{ - if (pcNode->mParent) { - pcNode->mTransformation = pcNode->mParent->mTransformation*pcNode->mTransformation; - } - - for (unsigned int i = 0;i < pcNode->mNumChildren;++i) { - ComputeAbsoluteTransform(pcNode->mChildren[i]); - } -} - -// ------------------------------------------------------------------------------------------------ -// Apply the node transformation to a mesh -void PretransformVertices::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat) -{ - // Check whether we need to transform the coordinates at all - if (!mat.IsIdentity()) { - - if (mesh->HasPositions()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - mesh->mVertices[i] = mat * mesh->mVertices[i]; - } - } - if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) { - aiMatrix4x4 mWorldIT = mat; - mWorldIT.Inverse().Transpose(); - - // TODO: implement Inverse() for aiMatrix3x3 - aiMatrix3x3 m = aiMatrix3x3(mWorldIT); - - if (mesh->HasNormals()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize(); - } - } - if (mesh->HasTangentsAndBitangents()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize(); - mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize(); - } - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Simple routine to build meshes in worldspace, no further optimization -void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in, - unsigned int numIn, aiNode* node) -{ - // NOTE: - // aiMesh::mNumBones store original source mesh, or UINT_MAX if not a copy - // aiMesh::mBones store reference to abs. transform we multiplied with - - // process meshes - for (unsigned int i = 0; i < node->mNumMeshes;++i) { - aiMesh* mesh = in[node->mMeshes[i]]; - - // check whether we can operate on this mesh - if (!mesh->mBones || *reinterpret_cast<aiMatrix4x4*>(mesh->mBones) == node->mTransformation) { - // yes, we can. - mesh->mBones = reinterpret_cast<aiBone**> (&node->mTransformation); - mesh->mNumBones = UINT_MAX; - } - else { - - // try to find us in the list of newly created meshes - for (unsigned int n = 0; n < out.size(); ++n) { - aiMesh* ctz = out[n]; - if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4*>(ctz->mBones) == node->mTransformation) { - - // ok, use this one. Update node mesh index - node->mMeshes[i] = numIn + n; - } - } - if (node->mMeshes[i] < numIn) { - // Worst case. Need to operate on a full copy of the mesh - ASSIMP_LOG_INFO("PretransformVertices: Copying mesh due to mismatching transforms"); - aiMesh* ntz; - - const unsigned int tmp = mesh->mNumBones; // - mesh->mNumBones = 0; - SceneCombiner::Copy(&ntz,mesh); - mesh->mNumBones = tmp; - - ntz->mNumBones = node->mMeshes[i]; - ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation); - - out.push_back(ntz); - - node->mMeshes[i] = static_cast<unsigned int>(numIn + out.size() - 1); - } - } - } - - // call children - for (unsigned int i = 0; i < node->mNumChildren;++i) - BuildWCSMeshes(out,in,numIn,node->mChildren[i]); -} - -// ------------------------------------------------------------------------------------------------ -// Reset transformation matrices to identity -void PretransformVertices::MakeIdentityTransform(aiNode* nd) -{ - nd->mTransformation = aiMatrix4x4(); - - // call children - for (unsigned int i = 0; i < nd->mNumChildren;++i) - MakeIdentityTransform(nd->mChildren[i]); -} - -// ------------------------------------------------------------------------------------------------ -// Build reference counters for all meshes -void PretransformVertices::BuildMeshRefCountArray(aiNode* nd, unsigned int * refs) -{ - for (unsigned int i = 0; i< nd->mNumMeshes;++i) - refs[nd->mMeshes[i]]++; - - // call children - for (unsigned int i = 0; i < nd->mNumChildren;++i) - BuildMeshRefCountArray(nd->mChildren[i],refs); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void PretransformVertices::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("PretransformVerticesProcess begin"); - - // Return immediately if we have no meshes - if (!pScene->mNumMeshes) - return; - - const unsigned int iOldMeshes = pScene->mNumMeshes; - const unsigned int iOldAnimationChannels = pScene->mNumAnimations; - const unsigned int iOldNodes = CountNodes(pScene->mRootNode); - - if(configTransform) { - pScene->mRootNode->mTransformation = configTransformation; - } - - // first compute absolute transformation matrices for all nodes - ComputeAbsoluteTransform(pScene->mRootNode); - - // Delete aiMesh::mBones for all meshes. The bones are - // removed during this step and we need the pointer as - // temporary storage - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) { - aiMesh* mesh = pScene->mMeshes[i]; - - for (unsigned int a = 0; a < mesh->mNumBones;++a) - delete mesh->mBones[a]; - - delete[] mesh->mBones; - mesh->mBones = NULL; - } - - // now build a list of output meshes - std::vector<aiMesh*> apcOutMeshes; - - // Keep scene hierarchy? It's an easy job in this case ... - // we go on and transform all meshes, if one is referenced by nodes - // with different absolute transformations a depth copy of the mesh - // is required. - if( configKeepHierarchy ) { - - // Hack: store the matrix we're transforming a mesh with in aiMesh::mBones - BuildWCSMeshes(apcOutMeshes,pScene->mMeshes,pScene->mNumMeshes, pScene->mRootNode); - - // ... if new meshes have been generated, append them to the end of the scene - if (apcOutMeshes.size() > 0) { - aiMesh** npp = new aiMesh*[pScene->mNumMeshes + apcOutMeshes.size()]; - - memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes); - memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size()); - - pScene->mNumMeshes += static_cast<unsigned int>(apcOutMeshes.size()); - delete[] pScene->mMeshes; pScene->mMeshes = npp; - } - - // now iterate through all meshes and transform them to worldspace - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - ApplyTransform(pScene->mMeshes[i],*reinterpret_cast<aiMatrix4x4*>( pScene->mMeshes[i]->mBones )); - - // prevent improper destruction - pScene->mMeshes[i]->mBones = NULL; - pScene->mMeshes[i]->mNumBones = 0; - } - } else { - apcOutMeshes.reserve(pScene->mNumMaterials<<1u); - std::list<unsigned int> aiVFormats; - - std::vector<unsigned int> s(pScene->mNumMeshes,0); - BuildMeshRefCountArray(pScene->mRootNode,&s[0]); - - for (unsigned int i = 0; i < pScene->mNumMaterials;++i) { - // get the list of all vertex formats for this material - aiVFormats.clear(); - GetVFormatList(pScene,i,aiVFormats); - aiVFormats.sort(); - aiVFormats.unique(); - for (std::list<unsigned int>::const_iterator j = aiVFormats.begin();j != aiVFormats.end();++j) { - unsigned int iVertices = 0; - unsigned int iFaces = 0; - CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices); - if (0 != iFaces && 0 != iVertices) - { - apcOutMeshes.push_back(new aiMesh()); - aiMesh* pcMesh = apcOutMeshes.back(); - pcMesh->mNumFaces = iFaces; - pcMesh->mNumVertices = iVertices; - pcMesh->mFaces = new aiFace[iFaces]; - pcMesh->mVertices = new aiVector3D[iVertices]; - pcMesh->mMaterialIndex = i; - if ((*j) & 0x2)pcMesh->mNormals = new aiVector3D[iVertices]; - if ((*j) & 0x4) - { - pcMesh->mTangents = new aiVector3D[iVertices]; - pcMesh->mBitangents = new aiVector3D[iVertices]; - } - iFaces = 0; - while ((*j) & (0x100 << iFaces)) - { - pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices]; - if ((*j) & (0x10000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3; - else pcMesh->mNumUVComponents[iFaces] = 2; - iFaces++; - } - iFaces = 0; - while ((*j) & (0x1000000 << iFaces)) - pcMesh->mColors[iFaces++] = new aiColor4D[iVertices]; - - // fill the mesh ... - unsigned int aiTemp[2] = {0,0}; - CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp,&s[0]); - } - } - } - - // If no meshes are referenced in the node graph it is possible that we get no output meshes. - if (apcOutMeshes.empty()) { - - throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes"); - } - else - { - // now delete all meshes in the scene and build a new mesh list - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) - { - aiMesh* mesh = pScene->mMeshes[i]; - mesh->mNumBones = 0; - mesh->mBones = NULL; - - // we're reusing the face index arrays. avoid destruction - for (unsigned int a = 0; a < mesh->mNumFaces; ++a) { - mesh->mFaces[a].mNumIndices = 0; - mesh->mFaces[a].mIndices = NULL; - } - - delete mesh; - - // Invalidate the contents of the old mesh array. We will most - // likely have less output meshes now, so the last entries of - // the mesh array are not overridden. We set them to NULL to - // make sure the developer gets notified when his application - // attempts to access these fields ... - mesh = NULL; - } - - // It is impossible that we have more output meshes than - // input meshes, so we can easily reuse the old mesh array - pScene->mNumMeshes = (unsigned int)apcOutMeshes.size(); - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) { - pScene->mMeshes[i] = apcOutMeshes[i]; - } - } - } - - // remove all animations from the scene - for (unsigned int i = 0; i < pScene->mNumAnimations;++i) - delete pScene->mAnimations[i]; - delete[] pScene->mAnimations; - - pScene->mAnimations = NULL; - pScene->mNumAnimations = 0; - - // --- we need to keep all cameras and lights - for (unsigned int i = 0; i < pScene->mNumCameras;++i) - { - aiCamera* cam = pScene->mCameras[i]; - const aiNode* nd = pScene->mRootNode->FindNode(cam->mName); - ai_assert(NULL != nd); - - // multiply all properties of the camera with the absolute - // transformation of the corresponding node - cam->mPosition = nd->mTransformation * cam->mPosition; - cam->mLookAt = aiMatrix3x3( nd->mTransformation ) * cam->mLookAt; - cam->mUp = aiMatrix3x3( nd->mTransformation ) * cam->mUp; - } - - for (unsigned int i = 0; i < pScene->mNumLights;++i) - { - aiLight* l = pScene->mLights[i]; - const aiNode* nd = pScene->mRootNode->FindNode(l->mName); - ai_assert(NULL != nd); - - // multiply all properties of the camera with the absolute - // transformation of the corresponding node - l->mPosition = nd->mTransformation * l->mPosition; - l->mDirection = aiMatrix3x3( nd->mTransformation ) * l->mDirection; - l->mUp = aiMatrix3x3( nd->mTransformation ) * l->mUp; - } - - if( !configKeepHierarchy ) { - - // now delete all nodes in the scene and build a new - // flat node graph with a root node and some level 1 children - aiNode* newRoot = new aiNode(); - newRoot->mName = pScene->mRootNode->mName; - delete pScene->mRootNode; - pScene->mRootNode = newRoot; - - if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras) - { - pScene->mRootNode->mNumMeshes = 1; - pScene->mRootNode->mMeshes = new unsigned int[1]; - pScene->mRootNode->mMeshes[0] = 0; - } - else - { - pScene->mRootNode->mNumChildren = pScene->mNumMeshes+pScene->mNumLights+pScene->mNumCameras; - aiNode** nodes = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren]; - - // generate mesh nodes - for (unsigned int i = 0; i < pScene->mNumMeshes;++i,++nodes) - { - aiNode* pcNode = new aiNode(); - *nodes = pcNode; - pcNode->mParent = pScene->mRootNode; - pcNode->mName = pScene->mMeshes[i]->mName; - - // setup mesh indices - pcNode->mNumMeshes = 1; - pcNode->mMeshes = new unsigned int[1]; - pcNode->mMeshes[0] = i; - } - // generate light nodes - for (unsigned int i = 0; i < pScene->mNumLights;++i,++nodes) - { - aiNode* pcNode = new aiNode(); - *nodes = pcNode; - pcNode->mParent = pScene->mRootNode; - pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "light_%u",i); - pScene->mLights[i]->mName = pcNode->mName; - } - // generate camera nodes - for (unsigned int i = 0; i < pScene->mNumCameras;++i,++nodes) - { - aiNode* pcNode = new aiNode(); - *nodes = pcNode; - pcNode->mParent = pScene->mRootNode; - pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"cam_%u",i); - pScene->mCameras[i]->mName = pcNode->mName; - } - } - } - else { - // ... and finally set the transformation matrix of all nodes to identity - MakeIdentityTransform(pScene->mRootNode); - } - - if (configNormalize) { - // compute the boundary of all meshes - aiVector3D min,max; - MinMaxChooser<aiVector3D> ()(min,max); - - for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) { - aiMesh* m = pScene->mMeshes[a]; - for (unsigned int i = 0; i < m->mNumVertices;++i) { - min = std::min(m->mVertices[i],min); - max = std::max(m->mVertices[i],max); - } - } - - // find the dominant axis - aiVector3D d = max-min; - const ai_real div = std::max(d.x,std::max(d.y,d.z))*ai_real( 0.5); - - d = min + d * (ai_real)0.5; - for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) { - aiMesh* m = pScene->mMeshes[a]; - for (unsigned int i = 0; i < m->mNumVertices;++i) { - m->mVertices[i] = (m->mVertices[i]-d)/div; - } - } - } - - // print statistics - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_DEBUG("PretransformVerticesProcess finished"); - - ASSIMP_LOG_INFO_F("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (", - CountNodes(pScene->mRootNode) ," output nodes)" ); - ASSIMP_LOG_INFO_F("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras." ); - ASSIMP_LOG_INFO_F("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")"); - } -} diff --git a/thirdparty/assimp/code/PostProcessing/PretransformVertices.h b/thirdparty/assimp/code/PostProcessing/PretransformVertices.h deleted file mode 100644 index b2982951e0..0000000000 --- a/thirdparty/assimp/code/PostProcessing/PretransformVertices.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file PretransformVertices.h - * @brief Defines a post processing step to pretransform all - * vertices in the scenegraph - */ -#ifndef AI_PRETRANSFORMVERTICES_H_INC -#define AI_PRETRANSFORMVERTICES_H_INC - -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> - -#include <list> -#include <vector> - -// Forward declarations -struct aiNode; - -class PretransformVerticesTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** The PretransformVertices pre-transforms all vertices in the node tree - * and removes the whole graph. The output is a list of meshes, one for - * each material. -*/ -class ASSIMP_API PretransformVertices : public BaseProcess { -public: - PretransformVertices (); - ~PretransformVertices (); - - // ------------------------------------------------------------------- - // Check whether step is active - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - // Execute step on a given scene - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - // Setup import settings - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** @brief Toggle the 'keep hierarchy' option - * @param keep true for keep configuration. - */ - void KeepHierarchy(bool keep) { - configKeepHierarchy = keep; - } - - // ------------------------------------------------------------------- - /** @brief Check whether 'keep hierarchy' is currently enabled. - * @return ... - */ - bool IsHierarchyKept() const { - return configKeepHierarchy; - } - -private: - // ------------------------------------------------------------------- - // Count the number of nodes - unsigned int CountNodes( aiNode* pcNode ); - - // ------------------------------------------------------------------- - // Get a bitwise combination identifying the vertex format of a mesh - unsigned int GetMeshVFormat(aiMesh* pcMesh); - - // ------------------------------------------------------------------- - // Count the number of vertices in the whole scene and a given - // material index - void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, - unsigned int iMat, - unsigned int iVFormat, - unsigned int* piFaces, - unsigned int* piVertices); - - // ------------------------------------------------------------------- - // Collect vertex/face data - void CollectData( aiScene* pcScene, aiNode* pcNode, - unsigned int iMat, - unsigned int iVFormat, - aiMesh* pcMeshOut, - unsigned int aiCurrent[2], - unsigned int* num_refs); - - // ------------------------------------------------------------------- - // Get a list of all vertex formats that occur for a given material - // The output list contains duplicate elements - void GetVFormatList( aiScene* pcScene, unsigned int iMat, - std::list<unsigned int>& aiOut); - - // ------------------------------------------------------------------- - // Compute the absolute transformation matrices of each node - void ComputeAbsoluteTransform( aiNode* pcNode ); - - // ------------------------------------------------------------------- - // Simple routine to build meshes in worldspace, no further optimization - void BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in, - unsigned int numIn, aiNode* node); - - // ------------------------------------------------------------------- - // Apply the node transformation to a mesh - void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat); - - // ------------------------------------------------------------------- - // Reset transformation matrices to identity - void MakeIdentityTransform(aiNode* nd); - - // ------------------------------------------------------------------- - // Build reference counters for all meshes - void BuildMeshRefCountArray(aiNode* nd, unsigned int * refs); - - //! Configuration option: keep scene hierarchy as long as possible - bool configKeepHierarchy; - bool configNormalize; - bool configTransform; - aiMatrix4x4 configTransformation; - bool mConfigPointCloud; -}; - -} // end of namespace Assimp - -#endif // !!AI_GENFACENORMALPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp b/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp deleted file mode 100644 index 59869fdff7..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/// @file ProcessHelper.cpp -/** Implement shared utility functions for postprocessing steps */ - - -#include "ProcessHelper.h" - - -#include <limits> - -namespace Assimp { - -// ------------------------------------------------------------------------------- -void ConvertListToStrings(const std::string& in, std::list<std::string>& out) -{ - const char* s = in.c_str(); - while (*s) { - SkipSpacesAndLineEnd(&s); - if (*s == '\'') { - const char* base = ++s; - while (*s != '\'') { - ++s; - if (*s == '\0') { - ASSIMP_LOG_ERROR("ConvertListToString: String list is ill-formatted"); - return; - } - } - out.push_back(std::string(base,(size_t)(s-base))); - ++s; - } - else { - out.push_back(GetNextToken(s)); - } - } -} - -// ------------------------------------------------------------------------------- -void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, - const aiMatrix4x4& m) -{ - min = aiVector3D ( ai_real( 10e10 ), ai_real( 10e10 ), ai_real( 10e10 ) ); - max = aiVector3D ( ai_real( -10e10 ), ai_real( -10e10 ), ai_real( -10e10 ) ); - for (unsigned int i = 0;i < mesh->mNumVertices;++i) - { - const aiVector3D v = m * mesh->mVertices[i]; - min = std::min(v,min); - max = std::max(v,max); - } -} - -// ------------------------------------------------------------------------------- -void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max) -{ - ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max); - out = min + (max-min)*(ai_real)0.5; -} - -// ------------------------------------------------------------------------------- -void FindSceneCenter (aiScene* scene, aiVector3D& out, aiVector3D& min, aiVector3D& max) { - if ( NULL == scene ) { - return; - } - - if ( 0 == scene->mNumMeshes ) { - return; - } - FindMeshCenter(scene->mMeshes[0], out, min, max); - for (unsigned int i = 1; i < scene->mNumMeshes; ++i) { - aiVector3D tout, tmin, tmax; - FindMeshCenter(scene->mMeshes[i], tout, tmin, tmax); - if (min[0] > tmin[0]) min[0] = tmin[0]; - if (min[1] > tmin[1]) min[1] = tmin[1]; - if (min[2] > tmin[2]) min[2] = tmin[2]; - if (max[0] < tmax[0]) max[0] = tmax[0]; - if (max[1] < tmax[1]) max[1] = tmax[1]; - if (max[2] < tmax[2]) max[2] = tmax[2]; - } - out = min + (max-min)*(ai_real)0.5; -} - - -// ------------------------------------------------------------------------------- -void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min, - aiVector3D& max, const aiMatrix4x4& m) -{ - FindAABBTransformed(mesh,min,max,m); - out = min + (max-min)*(ai_real)0.5; -} - -// ------------------------------------------------------------------------------- -void FindMeshCenter (aiMesh* mesh, aiVector3D& out) -{ - aiVector3D min,max; - FindMeshCenter(mesh,out,min,max); -} - -// ------------------------------------------------------------------------------- -void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, - const aiMatrix4x4& m) -{ - aiVector3D min,max; - FindMeshCenterTransformed(mesh,out,min,max,m); -} - -// ------------------------------------------------------------------------------- -ai_real ComputePositionEpsilon(const aiMesh* pMesh) -{ - const ai_real epsilon = ai_real( 1e-4 ); - - // calculate the position bounds so we have a reliable epsilon to check position differences against - aiVector3D minVec, maxVec; - ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec); - return (maxVec - minVec).Length() * epsilon; -} - -// ------------------------------------------------------------------------------- -ai_real ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num) -{ - ai_assert( NULL != pMeshes ); - - const ai_real epsilon = ai_real( 1e-4 ); - - // calculate the position bounds so we have a reliable epsilon to check position differences against - aiVector3D minVec, maxVec, mi, ma; - MinMaxChooser<aiVector3D>()(minVec,maxVec); - - for (size_t a = 0; a < num; ++a) { - const aiMesh* pMesh = pMeshes[a]; - ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma); - - minVec = std::min(minVec,mi); - maxVec = std::max(maxVec,ma); - } - return (maxVec - minVec).Length() * epsilon; -} - - -// ------------------------------------------------------------------------------- -unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh) -{ - ai_assert(NULL != pcMesh); - - // FIX: the hash may never be 0. Otherwise a comparison against - // nullptr could be successful - unsigned int iRet = 1; - - // normals - if (pcMesh->HasNormals())iRet |= 0x2; - // tangents and bitangents - if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4; - -#ifdef BOOST_STATIC_ASSERT - BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS); - BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS); -#endif - - // texture coordinates - unsigned int p = 0; - while (pcMesh->HasTextureCoords(p)) - { - iRet |= (0x100 << p); - if (3 == pcMesh->mNumUVComponents[p]) - iRet |= (0x10000 << p); - - ++p; - } - // vertex colors - p = 0; - while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++); - return iRet; -} - -// ------------------------------------------------------------------------------- -VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) -{ - if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) { - return NULL; - } - - VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices]; - for (unsigned int i = 0; i < pMesh->mNumBones;++i) { - - aiBone* bone = pMesh->mBones[i]; - for (unsigned int a = 0; a < bone->mNumWeights;++a) { - const aiVertexWeight& weight = bone->mWeights[a]; - avPerVertexWeights[weight.mVertexId].push_back( std::pair<unsigned int,float>(i,weight.mWeight) ); - } - } - return avPerVertexWeights; -} - - -// ------------------------------------------------------------------------------- -const char* TextureTypeToString(aiTextureType in) -{ - switch (in) - { - case aiTextureType_NONE: - return "n/a"; - case aiTextureType_DIFFUSE: - return "Diffuse"; - case aiTextureType_SPECULAR: - return "Specular"; - case aiTextureType_AMBIENT: - return "Ambient"; - case aiTextureType_EMISSIVE: - return "Emissive"; - case aiTextureType_OPACITY: - return "Opacity"; - case aiTextureType_NORMALS: - return "Normals"; - case aiTextureType_HEIGHT: - return "Height"; - case aiTextureType_SHININESS: - return "Shininess"; - case aiTextureType_DISPLACEMENT: - return "Displacement"; - case aiTextureType_LIGHTMAP: - return "Lightmap"; - case aiTextureType_REFLECTION: - return "Reflection"; - case aiTextureType_UNKNOWN: - return "Unknown"; - default: - break; - } - - ai_assert(false); - return "BUG"; -} - -// ------------------------------------------------------------------------------- -const char* MappingTypeToString(aiTextureMapping in) -{ - switch (in) - { - case aiTextureMapping_UV: - return "UV"; - case aiTextureMapping_BOX: - return "Box"; - case aiTextureMapping_SPHERE: - return "Sphere"; - case aiTextureMapping_CYLINDER: - return "Cylinder"; - case aiTextureMapping_PLANE: - return "Plane"; - case aiTextureMapping_OTHER: - return "Other"; - default: - break; - } - - ai_assert(false); - return "BUG"; -} - - -// ------------------------------------------------------------------------------- -aiMesh* MakeSubmesh(const aiMesh *pMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags) -{ - aiMesh *oMesh = new aiMesh(); - std::vector<unsigned int> vMap(pMesh->mNumVertices,UINT_MAX); - - size_t numSubVerts = 0; - size_t numSubFaces = subMeshFaces.size(); - - for(unsigned int i=0;i<numSubFaces;i++) { - const aiFace &f = pMesh->mFaces[subMeshFaces[i]]; - - for(unsigned int j=0;j<f.mNumIndices;j++) { - if(vMap[f.mIndices[j]]==UINT_MAX) { - vMap[f.mIndices[j]] = static_cast<unsigned int>(numSubVerts++); - } - } - } - - oMesh->mName = pMesh->mName; - - oMesh->mMaterialIndex = pMesh->mMaterialIndex; - oMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes; - - // create all the arrays for this mesh if the old mesh contained them - - oMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size()); - oMesh->mNumVertices = static_cast<unsigned int>(numSubVerts); - oMesh->mVertices = new aiVector3D[numSubVerts]; - if( pMesh->HasNormals() ) { - oMesh->mNormals = new aiVector3D[numSubVerts]; - } - - if( pMesh->HasTangentsAndBitangents() ) { - oMesh->mTangents = new aiVector3D[numSubVerts]; - oMesh->mBitangents = new aiVector3D[numSubVerts]; - } - - for( size_t a = 0; pMesh->HasTextureCoords(static_cast<unsigned int>(a)) ; ++a ) { - oMesh->mTextureCoords[a] = new aiVector3D[numSubVerts]; - oMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a]; - } - - for( size_t a = 0; pMesh->HasVertexColors( static_cast<unsigned int>(a)); ++a ) { - oMesh->mColors[a] = new aiColor4D[numSubVerts]; - } - - // and copy over the data, generating faces with linear indices along the way - oMesh->mFaces = new aiFace[numSubFaces]; - - for(unsigned int a = 0; a < numSubFaces; ++a ) { - - const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]]; - aiFace& dstFace = oMesh->mFaces[a]; - dstFace.mNumIndices = srcFace.mNumIndices; - dstFace.mIndices = new unsigned int[dstFace.mNumIndices]; - - // accumulate linearly all the vertices of the source face - for( size_t b = 0; b < dstFace.mNumIndices; ++b ) { - dstFace.mIndices[b] = vMap[srcFace.mIndices[b]]; - } - } - - for(unsigned int srcIndex = 0; srcIndex < pMesh->mNumVertices; ++srcIndex ) { - unsigned int nvi = vMap[srcIndex]; - if(nvi==UINT_MAX) { - continue; - } - - oMesh->mVertices[nvi] = pMesh->mVertices[srcIndex]; - if( pMesh->HasNormals() ) { - oMesh->mNormals[nvi] = pMesh->mNormals[srcIndex]; - } - - if( pMesh->HasTangentsAndBitangents() ) { - oMesh->mTangents[nvi] = pMesh->mTangents[srcIndex]; - oMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex]; - } - for( size_t c = 0, cc = pMesh->GetNumUVChannels(); c < cc; ++c ) { - oMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex]; - } - for( size_t c = 0, cc = pMesh->GetNumColorChannels(); c < cc; ++c ) { - oMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex]; - } - } - - if(~subFlags&AI_SUBMESH_FLAGS_SANS_BONES) { - std::vector<unsigned int> subBones(pMesh->mNumBones,0); - - for(unsigned int a=0;a<pMesh->mNumBones;++a) { - const aiBone* bone = pMesh->mBones[a]; - - for(unsigned int b=0;b<bone->mNumWeights;b++) { - unsigned int v = vMap[bone->mWeights[b].mVertexId]; - - if(v!=UINT_MAX) { - subBones[a]++; - } - } - } - - for(unsigned int a=0;a<pMesh->mNumBones;++a) { - if(subBones[a]>0) { - oMesh->mNumBones++; - } - } - - if(oMesh->mNumBones) { - oMesh->mBones = new aiBone*[oMesh->mNumBones](); - unsigned int nbParanoia = oMesh->mNumBones; - - oMesh->mNumBones = 0; //rewind - - for(unsigned int a=0;a<pMesh->mNumBones;++a) { - if(subBones[a]==0) { - continue; - } - aiBone *newBone = new aiBone; - oMesh->mBones[oMesh->mNumBones++] = newBone; - - const aiBone* bone = pMesh->mBones[a]; - - newBone->mName = bone->mName; - newBone->mOffsetMatrix = bone->mOffsetMatrix; - newBone->mWeights = new aiVertexWeight[subBones[a]]; - - for(unsigned int b=0;b<bone->mNumWeights;b++) { - const unsigned int v = vMap[bone->mWeights[b].mVertexId]; - - if(v!=UINT_MAX) { - aiVertexWeight w(v,bone->mWeights[b].mWeight); - newBone->mWeights[newBone->mNumWeights++] = w; - } - } - } - - ai_assert(nbParanoia==oMesh->mNumBones); - (void)nbParanoia; // remove compiler warning on release build - } - } - - return oMesh; -} - -} // namespace Assimp diff --git a/thirdparty/assimp/code/PostProcessing/ProcessHelper.h b/thirdparty/assimp/code/PostProcessing/ProcessHelper.h deleted file mode 100644 index 0afcc41420..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ProcessHelper.h +++ /dev/null @@ -1,386 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#ifndef AI_PROCESS_HELPER_H_INCLUDED -#define AI_PROCESS_HELPER_H_INCLUDED - -#include <assimp/postprocess.h> -#include <assimp/anim.h> -#include <assimp/mesh.h> -#include <assimp/material.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/scene.h> - -#include <assimp/SpatialSort.h> -#include "Common/BaseProcess.h" -#include <assimp/ParsingUtils.h> - -#include <list> - -// ------------------------------------------------------------------------------- -// Some extensions to std namespace. Mainly std::min and std::max for all -// flat data types in the aiScene. They're used to quickly determine the -// min/max bounds of data arrays. -#ifdef __cplusplus -namespace std { - - // std::min for aiVector3D - template <typename TReal> - inline ::aiVector3t<TReal> min (const ::aiVector3t<TReal>& a, const ::aiVector3t<TReal>& b) { - return ::aiVector3t<TReal> (min(a.x,b.x),min(a.y,b.y),min(a.z,b.z)); - } - - // std::max for aiVector3t<TReal> - template <typename TReal> - inline ::aiVector3t<TReal> max (const ::aiVector3t<TReal>& a, const ::aiVector3t<TReal>& b) { - return ::aiVector3t<TReal> (max(a.x,b.x),max(a.y,b.y),max(a.z,b.z)); - } - - // std::min for aiVector2t<TReal> - template <typename TReal> - inline ::aiVector2t<TReal> min (const ::aiVector2t<TReal>& a, const ::aiVector2t<TReal>& b) { - return ::aiVector2t<TReal> (min(a.x,b.x),min(a.y,b.y)); - } - - // std::max for aiVector2t<TReal> - template <typename TReal> - inline ::aiVector2t<TReal> max (const ::aiVector2t<TReal>& a, const ::aiVector2t<TReal>& b) { - return ::aiVector2t<TReal> (max(a.x,b.x),max(a.y,b.y)); - } - - // std::min for aiColor4D - template <typename TReal> - inline ::aiColor4t<TReal> min (const ::aiColor4t<TReal>& a, const ::aiColor4t<TReal>& b) { - return ::aiColor4t<TReal> (min(a.r,b.r),min(a.g,b.g),min(a.b,b.b),min(a.a,b.a)); - } - - // std::max for aiColor4D - template <typename TReal> - inline ::aiColor4t<TReal> max (const ::aiColor4t<TReal>& a, const ::aiColor4t<TReal>& b) { - return ::aiColor4t<TReal> (max(a.r,b.r),max(a.g,b.g),max(a.b,b.b),max(a.a,b.a)); - } - - - // std::min for aiQuaterniont<TReal> - template <typename TReal> - inline ::aiQuaterniont<TReal> min (const ::aiQuaterniont<TReal>& a, const ::aiQuaterniont<TReal>& b) { - return ::aiQuaterniont<TReal> (min(a.w,b.w),min(a.x,b.x),min(a.y,b.y),min(a.z,b.z)); - } - - // std::max for aiQuaterniont<TReal> - template <typename TReal> - inline ::aiQuaterniont<TReal> max (const ::aiQuaterniont<TReal>& a, const ::aiQuaterniont<TReal>& b) { - return ::aiQuaterniont<TReal> (max(a.w,b.w),max(a.x,b.x),max(a.y,b.y),max(a.z,b.z)); - } - - - - // std::min for aiVectorKey - inline ::aiVectorKey min (const ::aiVectorKey& a, const ::aiVectorKey& b) { - return ::aiVectorKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue)); - } - - // std::max for aiVectorKey - inline ::aiVectorKey max (const ::aiVectorKey& a, const ::aiVectorKey& b) { - return ::aiVectorKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue)); - } - - // std::min for aiQuatKey - inline ::aiQuatKey min (const ::aiQuatKey& a, const ::aiQuatKey& b) { - return ::aiQuatKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue)); - } - - // std::max for aiQuatKey - inline ::aiQuatKey max (const ::aiQuatKey& a, const ::aiQuatKey& b) { - return ::aiQuatKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue)); - } - - // std::min for aiVertexWeight - inline ::aiVertexWeight min (const ::aiVertexWeight& a, const ::aiVertexWeight& b) { - return ::aiVertexWeight (min(a.mVertexId,b.mVertexId),min(a.mWeight,b.mWeight)); - } - - // std::max for aiVertexWeight - inline ::aiVertexWeight max (const ::aiVertexWeight& a, const ::aiVertexWeight& b) { - return ::aiVertexWeight (max(a.mVertexId,b.mVertexId),max(a.mWeight,b.mWeight)); - } - -} // end namespace std -#endif // !! C++ - -namespace Assimp { - -// ------------------------------------------------------------------------------- -// Start points for ArrayBounds<T> for all supported Ts -template <typename T> -struct MinMaxChooser; - -template <> struct MinMaxChooser<float> { - void operator ()(float& min,float& max) { - max = -1e10f; - min = 1e10f; -}}; -template <> struct MinMaxChooser<double> { - void operator ()(double& min,double& max) { - max = -1e10; - min = 1e10; -}}; -template <> struct MinMaxChooser<unsigned int> { - void operator ()(unsigned int& min,unsigned int& max) { - max = 0; - min = (1u<<(sizeof(unsigned int)*8-1)); -}}; - -template <typename T> struct MinMaxChooser< aiVector3t<T> > { - void operator ()(aiVector3t<T>& min,aiVector3t<T>& max) { - max = aiVector3t<T>(-1e10f,-1e10f,-1e10f); - min = aiVector3t<T>( 1e10f, 1e10f, 1e10f); -}}; -template <typename T> struct MinMaxChooser< aiVector2t<T> > { - void operator ()(aiVector2t<T>& min,aiVector2t<T>& max) { - max = aiVector2t<T>(-1e10f,-1e10f); - min = aiVector2t<T>( 1e10f, 1e10f); - }}; -template <typename T> struct MinMaxChooser< aiColor4t<T> > { - void operator ()(aiColor4t<T>& min,aiColor4t<T>& max) { - max = aiColor4t<T>(-1e10f,-1e10f,-1e10f,-1e10f); - min = aiColor4t<T>( 1e10f, 1e10f, 1e10f, 1e10f); -}}; - -template <typename T> struct MinMaxChooser< aiQuaterniont<T> > { - void operator ()(aiQuaterniont<T>& min,aiQuaterniont<T>& max) { - max = aiQuaterniont<T>(-1e10f,-1e10f,-1e10f,-1e10f); - min = aiQuaterniont<T>( 1e10f, 1e10f, 1e10f, 1e10f); -}}; - -template <> struct MinMaxChooser<aiVectorKey> { - void operator ()(aiVectorKey& min,aiVectorKey& max) { - MinMaxChooser<double>()(min.mTime,max.mTime); - MinMaxChooser<aiVector3D>()(min.mValue,max.mValue); -}}; -template <> struct MinMaxChooser<aiQuatKey> { - void operator ()(aiQuatKey& min,aiQuatKey& max) { - MinMaxChooser<double>()(min.mTime,max.mTime); - MinMaxChooser<aiQuaternion>()(min.mValue,max.mValue); -}}; - -template <> struct MinMaxChooser<aiVertexWeight> { - void operator ()(aiVertexWeight& min,aiVertexWeight& max) { - MinMaxChooser<unsigned int>()(min.mVertexId,max.mVertexId); - MinMaxChooser<float>()(min.mWeight,max.mWeight); -}}; - -// ------------------------------------------------------------------------------- -/** @brief Find the min/max values of an array of Ts - * @param in Input array - * @param size Number of elements to process - * @param[out] min minimum value - * @param[out] max maximum value - */ -template <typename T> -inline void ArrayBounds(const T* in, unsigned int size, T& min, T& max) -{ - MinMaxChooser<T> ()(min,max); - for (unsigned int i = 0; i < size;++i) { - min = std::min(in[i],min); - max = std::max(in[i],max); - } -} - - -// ------------------------------------------------------------------------------- -/** Little helper function to calculate the quadratic difference - * of two colours. - * @param pColor1 First color - * @param pColor2 second color - * @return Quadratic color difference */ -inline ai_real GetColorDifference( const aiColor4D& pColor1, const aiColor4D& pColor2) -{ - const aiColor4D c (pColor1.r - pColor2.r, pColor1.g - pColor2.g, pColor1.b - pColor2.b, pColor1.a - pColor2.a); - return c.r*c.r + c.g*c.g + c.b*c.b + c.a*c.a; -} - - -// ------------------------------------------------------------------------------- -/** @brief Extract single strings from a list of identifiers - * @param in Input string list. - * @param out Receives a list of clean output strings - * @sdee #AI_CONFIG_PP_OG_EXCLUDE_LIST */ -void ConvertListToStrings(const std::string& in, std::list<std::string>& out); - - -// ------------------------------------------------------------------------------- -/** @brief Compute the AABB of a mesh after applying a given transform - * @param mesh Input mesh - * @param[out] min Receives minimum transformed vertex - * @param[out] max Receives maximum transformed vertex - * @param m Transformation matrix to be applied */ -void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, const aiMatrix4x4& m); - - -// ------------------------------------------------------------------------------- -/** @brief Helper function to determine the 'real' center of a mesh - * - * That is the center of its axis-aligned bounding box. - * @param mesh Input mesh - * @param[out] min Minimum vertex of the mesh - * @param[out] max maximum vertex of the mesh - * @param[out] out Center point */ -void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max); - -// ------------------------------------------------------------------------------- -/** @brief Helper function to determine the 'real' center of a scene - * - * That is the center of its axis-aligned bounding box. - * @param scene Input scene - * @param[out] min Minimum vertex of the scene - * @param[out] max maximum vertex of the scene - * @param[out] out Center point */ -void FindSceneCenter (aiScene* scene, aiVector3D& out, aiVector3D& min, aiVector3D& max); - - -// ------------------------------------------------------------------------------- -// Helper function to determine the 'real' center of a mesh after applying a given transform -void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,aiVector3D& max, const aiMatrix4x4& m); - - -// ------------------------------------------------------------------------------- -// Helper function to determine the 'real' center of a mesh -void FindMeshCenter (aiMesh* mesh, aiVector3D& out); - - -// ------------------------------------------------------------------------------- -// Helper function to determine the 'real' center of a mesh after applying a given transform -void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,const aiMatrix4x4& m); - - -// ------------------------------------------------------------------------------- -// Compute a good epsilon value for position comparisons on a mesh -ai_real ComputePositionEpsilon(const aiMesh* pMesh); - - -// ------------------------------------------------------------------------------- -// Compute a good epsilon value for position comparisons on a array of meshes -ai_real ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num); - - -// ------------------------------------------------------------------------------- -// Compute an unique value for the vertex format of a mesh -unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh); - - -// defs for ComputeVertexBoneWeightTable() -typedef std::pair <unsigned int,float> PerVertexWeight; -typedef std::vector <PerVertexWeight> VertexWeightTable; - -// ------------------------------------------------------------------------------- -// Compute a per-vertex bone weight table -VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh); - - -// ------------------------------------------------------------------------------- -// Get a string for a given aiTextureType -const char* TextureTypeToString(aiTextureType in); - - -// ------------------------------------------------------------------------------- -// Get a string for a given aiTextureMapping -const char* MappingTypeToString(aiTextureMapping in); - - -// flags for MakeSubmesh() -#define AI_SUBMESH_FLAGS_SANS_BONES 0x1 - -// ------------------------------------------------------------------------------- -// Split a mesh given a list of faces to be contained in the sub mesh -aiMesh* MakeSubmesh(const aiMesh *superMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags); - -// ------------------------------------------------------------------------------- -// Utility postprocess step to share the spatial sort tree between -// all steps which use it to speedup its computations. -class ComputeSpatialSortProcess : public BaseProcess -{ - bool IsActive( unsigned int pFlags) const - { - return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace | - aiProcess_GenNormals | aiProcess_JoinIdenticalVertices)); - } - - void Execute( aiScene* pScene) - { - typedef std::pair<SpatialSort, ai_real> _Type; - ASSIMP_LOG_DEBUG("Generate spatially-sorted vertex cache"); - - std::vector<_Type>* p = new std::vector<_Type>(pScene->mNumMeshes); - std::vector<_Type>::iterator it = p->begin(); - - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i, ++it) { - aiMesh* mesh = pScene->mMeshes[i]; - _Type& blubb = *it; - blubb.first.Fill(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D)); - blubb.second = ComputePositionEpsilon(mesh); - } - - shared->AddProperty(AI_SPP_SPATIAL_SORT,p); - } -}; - -// ------------------------------------------------------------------------------- -// ... and the same again to cleanup the whole stuff -class DestroySpatialSortProcess : public BaseProcess -{ - bool IsActive( unsigned int pFlags) const - { - return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace | - aiProcess_GenNormals | aiProcess_JoinIdenticalVertices)); - } - - void Execute( aiScene* /*pScene*/) - { - shared->RemoveProperty(AI_SPP_SPATIAL_SORT); - } -}; - - - -} // ! namespace Assimp -#endif // !! AI_PROCESS_HELPER_H_INCLUDED diff --git a/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp deleted file mode 100644 index 49ec8f5c47..0000000000 --- a/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file RemoveRedundantMaterials.cpp - * @brief Implementation of the "RemoveRedundantMaterials" post processing step -*/ - -// internal headers - -#include "RemoveRedundantMaterials.h" -#include <assimp/ParsingUtils.h> -#include "ProcessHelper.h" -#include "Material/MaterialSystem.h" -#include <stdio.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -RemoveRedundantMatsProcess::RemoveRedundantMatsProcess() -: mConfigFixedMaterials() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_RemoveRedundantMaterials) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Setup import properties -void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp) -{ - // Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST - mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,""); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void RemoveRedundantMatsProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin"); - - unsigned int redundantRemoved = 0, unreferencedRemoved = 0; - if (pScene->mNumMaterials) - { - // Find out which materials are referenced by meshes - std::vector<bool> abReferenced(pScene->mNumMaterials,false); - for (unsigned int i = 0;i < pScene->mNumMeshes;++i) - abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true; - - // If a list of materials to be excluded was given, match the list with - // our imported materials and 'salt' all positive matches to ensure that - // we get unique hashes later. - if (mConfigFixedMaterials.length()) { - - std::list<std::string> strings; - ConvertListToStrings(mConfigFixedMaterials,strings); - - for (unsigned int i = 0; i < pScene->mNumMaterials;++i) { - aiMaterial* mat = pScene->mMaterials[i]; - - aiString name; - mat->Get(AI_MATKEY_NAME,name); - - if (name.length) { - std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data); - if (it != strings.end()) { - - // Our brilliant 'salt': A single material property with ~ as first - // character to mark it as internal and temporary. - const int dummy = 1; - ((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0); - - // Keep this material even if no mesh references it - abReferenced[i] = true; - ASSIMP_LOG_DEBUG_F( "Found positive match in exclusion list: \'", name.data, "\'"); - } - } - } - } - - // TODO: re-implement this algorithm to work in-place - unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials]; - for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) { - aiMappingTable[ i ] = 0; - } - unsigned int iNewNum = 0; - - // Iterate through all materials and calculate a hash for them - // store all hashes in a list and so a quick search whether - // we do already have a specific hash. This allows us to - // determine which materials are identical. - uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];; - for (unsigned int i = 0; i < pScene->mNumMaterials;++i) - { - // No mesh is referencing this material, remove it. - if (!abReferenced[i]) { - ++unreferencedRemoved; - delete pScene->mMaterials[i]; - pScene->mMaterials[i] = nullptr; - continue; - } - - // Check all previously mapped materials for a matching hash. - // On a match we can delete this material and just make it ref to the same index. - uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]); - for (unsigned int a = 0; a < i;++a) - { - if (abReferenced[a] && me == aiHashes[a]) { - ++redundantRemoved; - me = 0; - aiMappingTable[i] = aiMappingTable[a]; - delete pScene->mMaterials[i]; - pScene->mMaterials[i] = nullptr; - break; - } - } - // This is a new material that is referenced, add to the map. - if (me) { - aiMappingTable[i] = iNewNum++; - } - } - // If the new material count differs from the original, - // we need to rebuild the material list and remap mesh material indexes. - if (iNewNum != pScene->mNumMaterials) { - ai_assert(iNewNum > 0); - aiMaterial** ppcMaterials = new aiMaterial*[iNewNum]; - ::memset(ppcMaterials,0,sizeof(void*)*iNewNum); - for (unsigned int p = 0; p < pScene->mNumMaterials;++p) - { - // if the material is not referenced ... remove it - if (!abReferenced[p]) { - continue; - } - - // generate new names for modified materials that had no names - const unsigned int idx = aiMappingTable[p]; - if (ppcMaterials[idx]) { - aiString sz; - if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) { - sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p); - ((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME); - } - } else { - ppcMaterials[idx] = pScene->mMaterials[p]; - } - } - // update all material indices - for (unsigned int p = 0; p < pScene->mNumMeshes;++p) { - aiMesh* mesh = pScene->mMeshes[p]; - ai_assert( NULL!=mesh ); - mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex]; - } - // delete the old material list - delete[] pScene->mMaterials; - pScene->mMaterials = ppcMaterials; - pScene->mNumMaterials = iNewNum; - } - // delete temporary storage - delete[] aiHashes; - delete[] aiMappingTable; - } - if (redundantRemoved == 0 && unreferencedRemoved == 0) - { - ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished "); - } - else - { - ASSIMP_LOG_INFO_F("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ", - unreferencedRemoved, " unused materials."); - } -} diff --git a/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h deleted file mode 100644 index 1f32a0abfb..0000000000 --- a/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file RemoveRedundantMaterials.h - * @brief Defines a post processing step to remove redundant materials - */ -#ifndef AI_REMOVEREDUNDANTMATERIALS_H_INC -#define AI_REMOVEREDUNDANTMATERIALS_H_INC - -#include "Common/BaseProcess.h" -#include <assimp/mesh.h> - -class RemoveRedundantMatsTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** RemoveRedundantMatsProcess: Post-processing step to remove redundant - * materials from the imported scene. - */ -class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess { -public: - /// The default class constructor. - RemoveRedundantMatsProcess(); - - /// The class destructor. - ~RemoveRedundantMatsProcess(); - - // ------------------------------------------------------------------- - // Check whether step is active - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - // Execute step on a given scene - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - // Setup import settings - void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** @brief Set list of fixed (inmutable) materials - * @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST - */ - void SetFixedMaterialsString(const std::string& fixed = "") { - mConfigFixedMaterials = fixed; - } - - // ------------------------------------------------------------------- - /** @brief Get list of fixed (inmutable) materials - * @return See #AI_CONFIG_PP_RRM_EXCLUDE_LIST - */ - const std::string& GetFixedMaterialsString() const { - return mConfigFixedMaterials; - } - -private: - //! Configuration option: list of all fixed materials - std::string mConfigFixedMaterials; -}; - -} // end of namespace Assimp - -#endif // !!AI_REMOVEREDUNDANTMATERIALS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp deleted file mode 100644 index 99fd47a3aa..0000000000 --- a/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file Implementation of the post processing step to remove - * any parts of the mesh structure from the imported data. -*/ - - -#include "RemoveVCProcess.h" -#include <assimp/postprocess.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/scene.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -RemoveVCProcess::RemoveVCProcess() : - configDeleteFlags() - , mScene() -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -RemoveVCProcess::~RemoveVCProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool RemoveVCProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_RemoveComponent) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Small helper function to delete all elements in a T** aray using delete -template <typename T> -inline void ArrayDelete(T**& in, unsigned int& num) -{ - for (unsigned int i = 0; i < num; ++i) - delete in[i]; - - delete[] in; - in = NULL; - num = 0; -} - -#if 0 -// ------------------------------------------------------------------------------------------------ -// Updates the node graph - removes all nodes which have the "remove" flag set and the -// "don't remove" flag not set. Nodes with meshes are never deleted. -bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root) -{ - bool b = false; - - std::list<aiNode*> mine; - for (unsigned int i = 0; i < node->mNumChildren;++i) - { - if(UpdateNodeGraph(node->mChildren[i],mine,false)) - b = true; - } - - // somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set, - // so we can do a simple comparison against MSB here - if (!root && AI_RC_UINT_MSB == node->mNumMeshes ) - { - // this node needs to be removed - if(node->mNumChildren) - { - childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end()); - - // set all children to NULL to make sure they are not deleted when we delete ourself - for (unsigned int i = 0; i < node->mNumChildren;++i) - node->mChildren[i] = NULL; - } - b = true; - delete node; - } - else - { - AI_RC_UNMASK(node->mNumMeshes); - childsOfParent.push_back(node); - - if (b) - { - // reallocate the array of our children here - node->mNumChildren = (unsigned int)mine.size(); - aiNode** const children = new aiNode*[mine.size()]; - aiNode** ptr = children; - - for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end(); - it != end; ++it) - { - *ptr++ = *it; - } - delete[] node->mChildren; - node->mChildren = children; - return false; - } - } - return b; -} -#endif - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void RemoveVCProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("RemoveVCProcess begin"); - bool bHas = false; //,bMasked = false; - - mScene = pScene; - - // handle animations - if ( configDeleteFlags & aiComponent_ANIMATIONS) - { - - bHas = true; - ArrayDelete(pScene->mAnimations,pScene->mNumAnimations); - } - - // handle textures - if ( configDeleteFlags & aiComponent_TEXTURES) - { - bHas = true; - ArrayDelete(pScene->mTextures,pScene->mNumTextures); - } - - // handle materials - if ( configDeleteFlags & aiComponent_MATERIALS && pScene->mNumMaterials) - { - bHas = true; - for (unsigned int i = 1;i < pScene->mNumMaterials;++i) - delete pScene->mMaterials[i]; - - pScene->mNumMaterials = 1; - aiMaterial* helper = (aiMaterial*) pScene->mMaterials[0]; - ai_assert(NULL != helper); - helper->Clear(); - - // gray - aiColor3D clr(0.6f,0.6f,0.6f); - helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE); - - // add a small ambient color value - clr = aiColor3D(0.05f,0.05f,0.05f); - helper->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT); - - aiString s; - s.Set("Dummy_MaterialsRemoved"); - helper->AddProperty(&s,AI_MATKEY_NAME); - } - - // handle light sources - if ( configDeleteFlags & aiComponent_LIGHTS) - { - bHas = true; - ArrayDelete(pScene->mLights,pScene->mNumLights); - } - - // handle camneras - if ( configDeleteFlags & aiComponent_CAMERAS) - { - bHas = true; - ArrayDelete(pScene->mCameras,pScene->mNumCameras); - } - - // handle meshes - if (configDeleteFlags & aiComponent_MESHES) - { - bHas = true; - ArrayDelete(pScene->mMeshes,pScene->mNumMeshes); - } - else - { - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) - { - if( ProcessMesh( pScene->mMeshes[a])) - bHas = true; - } - } - - - // now check whether the result is still a full scene - if (!pScene->mNumMeshes || !pScene->mNumMaterials) - { - pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - ASSIMP_LOG_DEBUG("Setting AI_SCENE_FLAGS_INCOMPLETE flag"); - - // If we have no meshes anymore we should also clear another flag ... - if (!pScene->mNumMeshes) - pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; - } - - if (bHas) { - ASSIMP_LOG_INFO("RemoveVCProcess finished. Data structure cleanup has been done."); - } else { - ASSIMP_LOG_DEBUG("RemoveVCProcess finished. Nothing to be done ..."); - } -} - -// ------------------------------------------------------------------------------------------------ -// Setup configuration properties for the step -void RemoveVCProcess::SetupProperties(const Importer* pImp) -{ - configDeleteFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,0x0); - if (!configDeleteFlags) - { - ASSIMP_LOG_WARN("RemoveVCProcess: AI_CONFIG_PP_RVC_FLAGS is zero."); - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh) -{ - bool ret = false; - - // if all materials have been deleted let the material - // index of the mesh point to the created default material - if ( configDeleteFlags & aiComponent_MATERIALS) - pMesh->mMaterialIndex = 0; - - // handle normals - if (configDeleteFlags & aiComponent_NORMALS && pMesh->mNormals) - { - delete[] pMesh->mNormals; - pMesh->mNormals = NULL; - ret = true; - } - - // handle tangents and bitangents - if (configDeleteFlags & aiComponent_TANGENTS_AND_BITANGENTS && pMesh->mTangents) - { - delete[] pMesh->mTangents; - pMesh->mTangents = NULL; - - delete[] pMesh->mBitangents; - pMesh->mBitangents = NULL; - ret = true; - } - - // handle texture coordinates - bool b = (0 != (configDeleteFlags & aiComponent_TEXCOORDS)); - for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++real) - { - if (!pMesh->mTextureCoords[i])break; - if (configDeleteFlags & aiComponent_TEXCOORDSn(real) || b) - { - delete [] pMesh->mTextureCoords[i]; - pMesh->mTextureCoords[i] = NULL; - ret = true; - - if (!b) - { - // collapse the rest of the array - for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) - pMesh->mTextureCoords[a-1] = pMesh->mTextureCoords[a]; - - pMesh->mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS-1] = NULL; - continue; - } - } - ++i; - } - - // handle vertex colors - b = (0 != (configDeleteFlags & aiComponent_COLORS)); - for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_COLOR_SETS; ++real) - { - if (!pMesh->mColors[i])break; - if (configDeleteFlags & aiComponent_COLORSn(i) || b) - { - delete [] pMesh->mColors[i]; - pMesh->mColors[i] = NULL; - ret = true; - - if (!b) - { - // collapse the rest of the array - for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) - pMesh->mColors[a-1] = pMesh->mColors[a]; - - pMesh->mColors[AI_MAX_NUMBER_OF_COLOR_SETS-1] = NULL; - continue; - } - } - ++i; - } - - // handle bones - if (configDeleteFlags & aiComponent_BONEWEIGHTS && pMesh->mBones) - { - ArrayDelete(pMesh->mBones,pMesh->mNumBones); - ret = true; - } - return ret; -} diff --git a/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h deleted file mode 100644 index 7bb21a8330..0000000000 --- a/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h +++ /dev/null @@ -1,124 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to remove specific parts of the scene */ -#ifndef AI_REMOVEVCPROCESS_H_INCLUDED -#define AI_REMOVEVCPROCESS_H_INCLUDED - -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> - -class RemoveVCProcessTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** RemoveVCProcess: Class to exclude specific parts of the data structure - * from further processing by removing them, -*/ -class ASSIMP_API RemoveVCProcess : public BaseProcess { -public: - /// The default class constructor. - RemoveVCProcess(); - - /// The class destructor. - ~RemoveVCProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - virtual void SetupProperties(const Importer* pImp); - - // ------------------------------------------------------------------- - /** Manually setup the configuration flags for the step - * - * @param Bitwise combination of the #aiComponent enumerated values. - */ - void SetDeleteFlags(unsigned int f) - { - configDeleteFlags = f; - } - - // ------------------------------------------------------------------- - /** Query the current configuration. - */ - unsigned int GetDeleteFlags() const - { - return configDeleteFlags; - } - -private: - - bool ProcessMesh (aiMesh* pcMesh); - - /** Configuration flag - */ - unsigned int configDeleteFlags; - - /** The scene we're working with - */ - aiScene* mScene; -}; - -// --------------------------------------------------------------------------- - -} // end of namespace Assimp - -#endif // !!AI_REMOVEVCPROCESS_H_INCLUDED diff --git a/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp deleted file mode 100644 index ac770c41f2..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#include "ScaleProcess.h" - -#include <assimp/scene.h> -#include <assimp/postprocess.h> -#include <assimp/BaseImporter.h> - -namespace Assimp { - -ScaleProcess::ScaleProcess() -: BaseProcess() -, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) { -} - -ScaleProcess::~ScaleProcess() { - // empty -} - -void ScaleProcess::setScale( ai_real scale ) { - mScale = scale; -} - -ai_real ScaleProcess::getScale() const { - return mScale; -} - -bool ScaleProcess::IsActive( unsigned int pFlags ) const { - return ( pFlags & aiProcess_GlobalScale ) != 0; -} - -void ScaleProcess::SetupProperties( const Importer* pImp ) { - // User scaling - mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f ); - - // File scaling * Application Scaling - float importerScale = pImp->GetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, 1.0f ); - - // apply scale to the scale - // helps prevent bugs with backward compatibility for anyone using normal scaling. - mScale *= importerScale; -} - -void ScaleProcess::Execute( aiScene* pScene ) { - if(mScale == 1.0f) { - return; // nothing to scale - } - - ai_assert( mScale != 0 ); - ai_assert( nullptr != pScene ); - ai_assert( nullptr != pScene->mRootNode ); - - if ( nullptr == pScene ) { - return; - } - - if ( nullptr == pScene->mRootNode ) { - return; - } - - // Process animations and update position transform to new unit system - for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ ) - { - aiAnimation* animation = pScene->mAnimations[animationID]; - - for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++) - { - aiNodeAnim* anim = animation->mChannels[animationChannel]; - - for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++) - { - aiVectorKey& vectorKey = anim->mPositionKeys[posKey]; - vectorKey.mValue *= mScale; - } - } - } - - for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++) - { - aiMesh *mesh = pScene->mMeshes[meshID]; - - // Reconstruct mesh vertexes to the new unit system - for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++) - { - aiVector3D& vertex = mesh->mVertices[vertexID]; - vertex *= mScale; - } - - - // bone placement / scaling - for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++) - { - // Reconstruct matrix by transform rather than by scale - // This prevent scale values being changed which can - // be meaningful in some cases - // like when you want the modeller to see 1:1 compatibility. - aiBone* bone = mesh->mBones[boneID]; - - aiVector3D pos, scale; - aiQuaternion rotation; - - bone->mOffsetMatrix.Decompose( scale, rotation, pos); - - aiMatrix4x4 translation; - aiMatrix4x4::Translation( pos * mScale, translation ); - - aiMatrix4x4 scaling; - aiMatrix4x4::Scaling( aiVector3D(scale), scaling ); - - aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix()); - - bone->mOffsetMatrix = translation * RotMatrix * scaling; - } - - - // animation mesh processing - // convert by position rather than scale. - for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++) - { - aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID]; - - for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++) - { - aiVector3D& vertex = animMesh->mVertices[vertexID]; - vertex *= mScale; - } - } - } - - traverseNodes( pScene->mRootNode ); -} - -void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) { - applyScaling( node ); - - for( size_t i = 0; i < node->mNumChildren; i++) - { - // recurse into the tree until we are done! - traverseNodes( node->mChildren[i], nested_node_id+1 ); - } -} - -void ScaleProcess::applyScaling( aiNode *currentNode ) { - if ( nullptr != currentNode ) { - // Reconstruct matrix by transform rather than by scale - // This prevent scale values being changed which can - // be meaningful in some cases - // like when you want the modeller to - // see 1:1 compatibility. - - aiVector3D pos, scale; - aiQuaternion rotation; - currentNode->mTransformation.Decompose( scale, rotation, pos); - - aiMatrix4x4 translation; - aiMatrix4x4::Translation( pos * mScale, translation ); - - aiMatrix4x4 scaling; - - // note: we do not use mScale here, this is on purpose. - aiMatrix4x4::Scaling( scale, scaling ); - - aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix()); - - currentNode->mTransformation = translation * RotMatrix * scaling; - } -} - -} // Namespace Assimp diff --git a/thirdparty/assimp/code/PostProcessing/ScaleProcess.h b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h deleted file mode 100644 index 468a216736..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ScaleProcess.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#ifndef SCALE_PROCESS_H_ -#define SCALE_PROCESS_H_ - -#include "Common/BaseProcess.h" - -struct aiNode; - -#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT) -# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f -#endif // !! AI_DEBONE_THRESHOLD - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** ScaleProcess: Class to rescale the whole model. - * Now rescales animations, bones, and blend shapes properly. - * Please note this will not write to 'scale' transform it will rewrite mesh - * and matrixes so that your scale values - * from your model package are preserved, so this is completely intentional - * bugs should be reported as soon as they are found. -*/ -class ASSIMP_API ScaleProcess : public BaseProcess { -public: - /// The default class constructor. - ScaleProcess(); - - /// The class destructor. - virtual ~ScaleProcess(); - - /// Will set the scale manually. - void setScale( ai_real scale ); - - /// Returns the current scaling value. - ai_real getScale() const; - - /// Overwritten, @see BaseProcess - virtual bool IsActive( unsigned int pFlags ) const; - - /// Overwritten, @see BaseProcess - virtual void SetupProperties( const Importer* pImp ); - - /// Overwritten, @see BaseProcess - virtual void Execute( aiScene* pScene ); - -private: - void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 ); - void applyScaling( aiNode *currentNode ); - -private: - ai_real mScale; -}; - -} // Namespace Assimp - - -#endif // SCALE_PROCESS_H_
\ No newline at end of file diff --git a/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp deleted file mode 100644 index be8405a17b..0000000000 --- a/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the DeterminePTypeHelperProcess and - * SortByPTypeProcess post-process steps. -*/ - - - -// internal headers -#include "ProcessHelper.h" -#include "SortByPTypeProcess.h" -#include <assimp/Exceptional.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -SortByPTypeProcess::SortByPTypeProcess() -: mConfigRemoveMeshes( 0 ) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -SortByPTypeProcess::~SortByPTypeProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool SortByPTypeProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_SortByPType) != 0; -} - -// ------------------------------------------------------------------------------------------------ -void SortByPTypeProcess::SetupProperties(const Importer* pImp) -{ - mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0); -} - -// ------------------------------------------------------------------------------------------------ -// Update changed meshes in all nodes -void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node) -{ - if (node->mNumMeshes) - { - unsigned int newSize = 0; - for (unsigned int m = 0; m< node->mNumMeshes; ++m) - { - unsigned int add = node->mMeshes[m]<<2; - for (unsigned int i = 0; i < 4;++i) - { - if (UINT_MAX != replaceMeshIndex[add+i])++newSize; - } - } - if (!newSize) - { - delete[] node->mMeshes; - node->mNumMeshes = 0; - node->mMeshes = NULL; - } - else - { - // Try to reuse the old array if possible - unsigned int* newMeshes = (newSize > node->mNumMeshes - ? new unsigned int[newSize] : node->mMeshes); - - for (unsigned int m = 0; m< node->mNumMeshes; ++m) - { - unsigned int add = node->mMeshes[m]<<2; - for (unsigned int i = 0; i < 4;++i) - { - if (UINT_MAX != replaceMeshIndex[add+i]) - *newMeshes++ = replaceMeshIndex[add+i]; - } - } - if (newSize > node->mNumMeshes) - delete[] node->mMeshes; - - node->mMeshes = newMeshes-(node->mNumMeshes = newSize); - } - } - - // call all subnodes recursively - for (unsigned int m = 0; m < node->mNumChildren; ++m) - UpdateNodes(replaceMeshIndex,node->mChildren[m]); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void SortByPTypeProcess::Execute( aiScene* pScene) { - if ( 0 == pScene->mNumMeshes) { - ASSIMP_LOG_DEBUG("SortByPTypeProcess skipped, there are no meshes"); - return; - } - - ASSIMP_LOG_DEBUG("SortByPTypeProcess begin"); - - unsigned int aiNumMeshesPerPType[4] = {0,0,0,0}; - - std::vector<aiMesh*> outMeshes; - outMeshes.reserve(pScene->mNumMeshes<<1u); - - bool bAnyChanges = false; - - std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*4,UINT_MAX); - std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin(); - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - aiMesh* const mesh = pScene->mMeshes[i]; - ai_assert(0 != mesh->mPrimitiveTypes); - - // if there's just one primitive type in the mesh there's nothing to do for us - unsigned int num = 0; - if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT) { - ++aiNumMeshesPerPType[0]; - ++num; - } - if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE) { - ++aiNumMeshesPerPType[1]; - ++num; - } - if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) { - ++aiNumMeshesPerPType[2]; - ++num; - } - if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON) { - ++aiNumMeshesPerPType[3]; - ++num; - } - - if (1 == num) { - if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) { - *meshIdx = static_cast<unsigned int>( outMeshes.size() ); - outMeshes.push_back(mesh); - } else { - delete mesh; - pScene->mMeshes[ i ] = nullptr; - bAnyChanges = true; - } - - meshIdx += 4; - continue; - } - bAnyChanges = true; - - // reuse our current mesh arrays for the submesh - // with the largest number of primitives - unsigned int aiNumPerPType[4] = {0,0,0,0}; - aiFace* pFirstFace = mesh->mFaces; - aiFace* const pLastFace = pFirstFace + mesh->mNumFaces; - - unsigned int numPolyVerts = 0; - for (;pFirstFace != pLastFace; ++pFirstFace) { - if (pFirstFace->mNumIndices <= 3) - ++aiNumPerPType[pFirstFace->mNumIndices-1]; - else - { - ++aiNumPerPType[3]; - numPolyVerts += pFirstFace-> mNumIndices; - } - } - - VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh); - for (unsigned int real = 0; real < 4; ++real,++meshIdx) - { - if ( !aiNumPerPType[real] || mConfigRemoveMeshes & (1u << real)) - { - continue; - } - - *meshIdx = (unsigned int) outMeshes.size(); - outMeshes.push_back(new aiMesh()); - aiMesh* out = outMeshes.back(); - - // the name carries the adjacency information between the meshes - out->mName = mesh->mName; - - // copy data members - out->mPrimitiveTypes = 1u << real; - out->mMaterialIndex = mesh->mMaterialIndex; - - // allocate output storage - out->mNumFaces = aiNumPerPType[real]; - aiFace* outFaces = out->mFaces = new aiFace[out->mNumFaces]; - - out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1)); - - aiVector3D *vert(nullptr), *nor(nullptr), *tan(nullptr), *bit(nullptr); - aiVector3D *uv [AI_MAX_NUMBER_OF_TEXTURECOORDS]; - aiColor4D *cols [AI_MAX_NUMBER_OF_COLOR_SETS]; - - if (mesh->mVertices) { - vert = out->mVertices = new aiVector3D[out->mNumVertices]; - } - - if (mesh->mNormals) { - nor = out->mNormals = new aiVector3D[out->mNumVertices]; - } - - if (mesh->mTangents) { - tan = out->mTangents = new aiVector3D[out->mNumVertices]; - bit = out->mBitangents = new aiVector3D[out->mNumVertices]; - } - - for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS;++j) { - uv[j] = nullptr; - if (mesh->mTextureCoords[j]) { - uv[j] = out->mTextureCoords[j] = new aiVector3D[out->mNumVertices]; - } - - out->mNumUVComponents[j] = mesh->mNumUVComponents[j]; - } - - for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS;++j) { - cols[j] = nullptr; - if (mesh->mColors[j]) { - cols[j] = out->mColors[j] = new aiColor4D[out->mNumVertices]; - } - } - - typedef std::vector< aiVertexWeight > TempBoneInfo; - std::vector< TempBoneInfo > tempBones(mesh->mNumBones); - - // try to guess how much storage we'll need - for (unsigned int q = 0; q < mesh->mNumBones;++q) - { - tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num-1)); - } - - unsigned int outIdx = 0; - for (unsigned int m = 0; m < mesh->mNumFaces; ++m) - { - aiFace& in = mesh->mFaces[m]; - if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real+1)) - { - continue; - } - - outFaces->mNumIndices = in.mNumIndices; - outFaces->mIndices = in.mIndices; - - for (unsigned int q = 0; q < in.mNumIndices; ++q) - { - unsigned int idx = in.mIndices[q]; - - // process all bones of this index - if (avw) - { - VertexWeightTable& tbl = avw[idx]; - for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end(); - it != end; ++it) - { - tempBones[ (*it).first ].push_back( aiVertexWeight(outIdx, (*it).second) ); - } - } - - if (vert) - { - *vert++ = mesh->mVertices[idx]; - //mesh->mVertices[idx].x = get_qnan(); - } - if (nor )*nor++ = mesh->mNormals[idx]; - if (tan ) - { - *tan++ = mesh->mTangents[idx]; - *bit++ = mesh->mBitangents[idx]; - } - - for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp) - { - if (!uv[pp])break; - *uv[pp]++ = mesh->mTextureCoords[pp][idx]; - } - - for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp) - { - if (!cols[pp])break; - *cols[pp]++ = mesh->mColors[pp][idx]; - } - - in.mIndices[q] = outIdx++; - } - - in.mIndices = nullptr; - ++outFaces; - } - ai_assert(outFaces == out->mFaces + out->mNumFaces); - - // now generate output bones - for (unsigned int q = 0; q < mesh->mNumBones;++q) - if (!tempBones[q].empty())++out->mNumBones; - - if (out->mNumBones) - { - out->mBones = new aiBone*[out->mNumBones]; - for (unsigned int q = 0, real = 0; q < mesh->mNumBones;++q) - { - TempBoneInfo& in = tempBones[q]; - if (in.empty())continue; - - aiBone* srcBone = mesh->mBones[q]; - aiBone* bone = out->mBones[real] = new aiBone(); - - bone->mName = srcBone->mName; - bone->mOffsetMatrix = srcBone->mOffsetMatrix; - - bone->mNumWeights = (unsigned int)in.size(); - bone->mWeights = new aiVertexWeight[bone->mNumWeights]; - - ::memcpy(bone->mWeights,&in[0],bone->mNumWeights*sizeof(aiVertexWeight)); - - ++real; - } - } - } - - // delete the per-vertex bone weights table - delete[] avw; - - // delete the input mesh - delete mesh; - - // avoid invalid pointer - pScene->mMeshes[i] = NULL; - } - - if (outMeshes.empty()) - { - // This should not occur - throw DeadlyImportError("No meshes remaining"); - } - - // If we added at least one mesh process all nodes in the node - // graph and update their respective mesh indices. - if (bAnyChanges) - { - UpdateNodes(replaceMeshIndex,pScene->mRootNode); - } - - if (outMeshes.size() != pScene->mNumMeshes) - { - delete[] pScene->mMeshes; - pScene->mNumMeshes = (unsigned int)outMeshes.size(); - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - } - ::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*)); - - if (!DefaultLogger::isNullLogger()) - { - char buffer[1024]; - ::ai_snprintf(buffer,1024,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)", - aiNumMeshesPerPType[0], ((mConfigRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""), - aiNumMeshesPerPType[1], ((mConfigRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""), - aiNumMeshesPerPType[2], ((mConfigRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""), - aiNumMeshesPerPType[3], ((mConfigRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : "")); - ASSIMP_LOG_INFO(buffer); - ASSIMP_LOG_DEBUG("SortByPTypeProcess finished"); - } -} - diff --git a/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h deleted file mode 100644 index 1d7ccfc152..0000000000 --- a/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to sort meshes by the types - of primitives they contain */ -#ifndef AI_SORTBYPTYPEPROCESS_H_INC -#define AI_SORTBYPTYPEPROCESS_H_INC - -#include "Common/BaseProcess.h" -#include <assimp/mesh.h> - -class SortByPTypeProcessTest; - -namespace Assimp { - - -// --------------------------------------------------------------------------- -/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain. - * A mesh with 5 lines, 3 points and 145 triangles would be split in 3 - * submeshes. -*/ -class ASSIMP_API SortByPTypeProcess : public BaseProcess { -public: - SortByPTypeProcess(); - ~SortByPTypeProcess(); - - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - void SetupProperties(const Importer* pImp); - -private: - int mConfigRemoveMeshes; -}; - - -} // end of namespace Assimp - -#endif // !!AI_SORTBYPTYPEPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp deleted file mode 100644 index 1797b28d5a..0000000000 --- a/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp +++ /dev/null @@ -1,623 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** - * @file Implementation of the SplitLargeMeshes postprocessing step - */ - -// internal headers of the post-processing framework -#include "SplitLargeMeshes.h" -#include "ProcessHelper.h" - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() { - LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES; -} - -// ------------------------------------------------------------------------------------------------ -SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const { - return (pFlags & aiProcess_SplitLargeMeshes) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) { - if (0xffffffff == this->LIMIT || nullptr == pScene ) { - return; - } - - ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle begin"); - std::vector<std::pair<aiMesh*, unsigned int> > avList; - - for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) { - this->SplitMesh(a, pScene->mMeshes[a],avList); - } - - if (avList.size() != pScene->mNumMeshes) { - // it seems something has been split. rebuild the mesh list - delete[] pScene->mMeshes; - pScene->mNumMeshes = (unsigned int)avList.size(); - pScene->mMeshes = new aiMesh*[avList.size()]; - - for (unsigned int i = 0; i < avList.size();++i) { - pScene->mMeshes[i] = avList[i].first; - } - - // now we need to update all nodes - this->UpdateNode(pScene->mRootNode,avList); - ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split"); - } else { - ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Setup properties -void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) { - // get the current value of the split property - this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES); -} - -// ------------------------------------------------------------------------------------------------ -// Update a node after some meshes have been split -void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode, - const std::vector<std::pair<aiMesh*, unsigned int> >& avList) { - // for every index in out list build a new entry - std::vector<unsigned int> aiEntries; - aiEntries.reserve(pcNode->mNumMeshes + 1); - for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) { - for (unsigned int a = 0; a < avList.size();++a) { - if (avList[a].second == pcNode->mMeshes[i]) { - aiEntries.push_back(a); - } - } - } - - // now build the new list - delete[] pcNode->mMeshes; - pcNode->mNumMeshes = (unsigned int)aiEntries.size(); - pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes]; - - for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) { - pcNode->mMeshes[b] = aiEntries[b]; - } - - // recusively update all other nodes - for (unsigned int i = 0; i < pcNode->mNumChildren;++i) { - UpdateNode ( pcNode->mChildren[i], avList ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void SplitLargeMeshesProcess_Triangle::SplitMesh( - unsigned int a, - aiMesh* pMesh, - std::vector<std::pair<aiMesh*, unsigned int> >& avList) { - if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT) { - ASSIMP_LOG_INFO("Mesh exceeds the triangle limit. It will be split ..."); - - // we need to split this mesh into sub meshes - // determine the size of a submesh - const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1; - - const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes; - const unsigned int iOutVertexNum = iOutFaceNum * 3; - - // now generate all submeshes - for (unsigned int i = 0; i < iSubMeshes;++i) { - aiMesh* pcMesh = new aiMesh; - pcMesh->mNumFaces = iOutFaceNum; - pcMesh->mMaterialIndex = pMesh->mMaterialIndex; - - // the name carries the adjacency information between the meshes - pcMesh->mName = pMesh->mName; - - if (i == iSubMeshes-1) { - pcMesh->mNumFaces = iOutFaceNum + ( - pMesh->mNumFaces - iOutFaceNum * iSubMeshes); - } - // copy the list of faces - pcMesh->mFaces = new aiFace[pcMesh->mNumFaces]; - - const unsigned int iBase = iOutFaceNum * i; - - // get the total number of indices - unsigned int iCnt = 0; - for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p) { - iCnt += pMesh->mFaces[p].mNumIndices; - } - pcMesh->mNumVertices = iCnt; - - // allocate storage - if (pMesh->mVertices != nullptr) { - pcMesh->mVertices = new aiVector3D[iCnt]; - } - - if (pMesh->HasNormals()) { - pcMesh->mNormals = new aiVector3D[iCnt]; - } - - if (pMesh->HasTangentsAndBitangents()) { - pcMesh->mTangents = new aiVector3D[iCnt]; - pcMesh->mBitangents = new aiVector3D[iCnt]; - } - - // texture coordinates - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { - pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c]; - if (pMesh->HasTextureCoords( c)) { - pcMesh->mTextureCoords[c] = new aiVector3D[iCnt]; - } - } - - // vertex colors - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) { - if (pMesh->HasVertexColors( c)) { - pcMesh->mColors[c] = new aiColor4D[iCnt]; - } - } - - if (pMesh->HasBones()) { - // assume the number of bones won't change in most cases - pcMesh->mBones = new aiBone*[pMesh->mNumBones]; - - // iterate through all bones of the mesh and find those which - // need to be copied to the split mesh - std::vector<aiVertexWeight> avTempWeights; - for (unsigned int p = 0; p < pcMesh->mNumBones;++p) { - aiBone* const bone = pcMesh->mBones[p]; - avTempWeights.clear(); - avTempWeights.reserve(bone->mNumWeights / iSubMeshes); - - for (unsigned int q = 0; q < bone->mNumWeights;++q) { - aiVertexWeight& weight = bone->mWeights[q]; - if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum) { - avTempWeights.push_back(weight); - weight = avTempWeights.back(); - weight.mVertexId -= iBase; - } - } - - if (!avTempWeights.empty()) { - // we'll need this bone. Copy it ... - aiBone* pc = new aiBone(); - pcMesh->mBones[pcMesh->mNumBones++] = pc; - pc->mName = aiString(bone->mName); - pc->mNumWeights = (unsigned int)avTempWeights.size(); - pc->mOffsetMatrix = bone->mOffsetMatrix; - - // no need to reallocate the array for the last submesh. - // Here we can reuse the (large) source array, although - // we'll waste some memory - if (iSubMeshes-1 == i) { - pc->mWeights = bone->mWeights; - bone->mWeights = nullptr; - } else { - pc->mWeights = new aiVertexWeight[pc->mNumWeights]; - } - - // copy the weights - ::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights); - } - } - } - - // (we will also need to copy the array of indices) - unsigned int iCurrent = 0; - for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) { - pcMesh->mFaces[p].mNumIndices = 3; - // allocate a new array - const unsigned int iTemp = p + iBase; - const unsigned int iNumIndices = pMesh->mFaces[iTemp].mNumIndices; - - // setup face type and number of indices - pcMesh->mFaces[p].mNumIndices = iNumIndices; - unsigned int* pi = pMesh->mFaces[iTemp].mIndices; - unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices]; - - // need to update the output primitive types - switch (iNumIndices) { - case 1: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - case 2: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - case 3: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - default: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - } - - // and copy the contents of the old array, offset by current base - for (unsigned int v = 0; v < iNumIndices;++v) { - unsigned int iIndex = pi[v]; - unsigned int iIndexOut = iCurrent++; - piOut[v] = iIndexOut; - - // copy positions - if (pMesh->mVertices != nullptr) { - pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex]; - } - - // copy normals - if (pMesh->HasNormals()) { - pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex]; - } - - // copy tangents/bitangents - if (pMesh->HasTangentsAndBitangents()) { - pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex]; - pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex]; - } - - // texture coordinates - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { - if (pMesh->HasTextureCoords( c ) ) { - pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex]; - } - } - // vertex colors - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) { - if (pMesh->HasVertexColors( c)) { - pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex]; - } - } - } - } - - // add the newly created mesh to the list - avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a)); - } - - // now delete the old mesh data - delete pMesh; - } else { - avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a)); - } -} - -// ------------------------------------------------------------------------------------------------ -SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() { - LIMIT = AI_SLM_DEFAULT_MAX_VERTICES; -} - -// ------------------------------------------------------------------------------------------------ -SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex() { - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const { - return (pFlags & aiProcess_SplitLargeMeshes) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene) { - if (0xffffffff == this->LIMIT || nullptr == pScene ) { - return; - } - - ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex begin"); - - std::vector<std::pair<aiMesh*, unsigned int> > avList; - - //Check for point cloud first, - //Do not process point cloud, splitMesh works only with faces data - for (unsigned int a = 0; a < pScene->mNumMeshes; a++) { - if ( pScene->mMeshes[a]->mPrimitiveTypes == aiPrimitiveType_POINT ) { - return; - } - } - - for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) { - this->SplitMesh(a, pScene->mMeshes[a], avList); - } - - if (avList.size() != pScene->mNumMeshes) { - // it seems something has been split. rebuild the mesh list - delete[] pScene->mMeshes; - pScene->mNumMeshes = (unsigned int)avList.size(); - pScene->mMeshes = new aiMesh*[avList.size()]; - - for (unsigned int i = 0; i < avList.size();++i) { - pScene->mMeshes[i] = avList[i].first; - } - - // now we need to update all nodes - SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList); - ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Vertex finished. Meshes have been split"); - } else { - ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex finished. There was nothing to do"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Setup properties -void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp) { - this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES); -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void SplitLargeMeshesProcess_Vertex::SplitMesh( - unsigned int a, - aiMesh* pMesh, - std::vector<std::pair<aiMesh*, unsigned int> >& avList) { - if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT) { - typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable; - - // build a per-vertex weight list if necessary - VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh); - - // we need to split this mesh into sub meshes - // determine the estimated size of a submesh - // (this could be too large. Max waste is a single digit percentage) - const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1; - - // create a std::vector<unsigned int> to indicate which vertices - // have already been copied - std::vector<unsigned int> avWasCopied; - avWasCopied.resize(pMesh->mNumVertices,0xFFFFFFFF); - - // try to find a good estimate for the number of output faces - // per mesh. Add 12.5% as buffer - unsigned int iEstimatedSize = pMesh->mNumFaces / iSubMeshes; - iEstimatedSize += iEstimatedSize >> 3; - - // now generate all submeshes - unsigned int iBase( 0 ); - while (true) { - const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT; - aiMesh* pcMesh = new aiMesh; - pcMesh->mNumVertices = 0; - pcMesh->mMaterialIndex = pMesh->mMaterialIndex; - - // the name carries the adjacency information between the meshes - pcMesh->mName = pMesh->mName; - - typedef std::vector<aiVertexWeight> BoneWeightList; - if (pMesh->HasBones()) { - pcMesh->mBones = new aiBone*[pMesh->mNumBones]; - ::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones); - } - - // clear the temporary helper array - if (iBase) { - // we can't use memset here we unsigned int needn' be 32 bits - for (auto &elem : avWasCopied) { - elem = 0xffffffff; - } - } - - // output vectors - std::vector<aiFace> vFaces; - - // reserve enough storage for most cases - if (pMesh->HasPositions()) { - pcMesh->mVertices = new aiVector3D[iOutVertexNum]; - } - if (pMesh->HasNormals()) { - pcMesh->mNormals = new aiVector3D[iOutVertexNum]; - } - if (pMesh->HasTangentsAndBitangents()) { - pcMesh->mTangents = new aiVector3D[iOutVertexNum]; - pcMesh->mBitangents = new aiVector3D[iOutVertexNum]; - } - for (unsigned int c = 0; pMesh->HasVertexColors(c);++c) { - pcMesh->mColors[c] = new aiColor4D[iOutVertexNum]; - } - for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c) { - pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c]; - pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum]; - } - vFaces.reserve(iEstimatedSize); - - // (we will also need to copy the array of indices) - while (iBase < pMesh->mNumFaces) { - // allocate a new array - const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices; - - // doesn't catch degenerates but is quite fast - unsigned int iNeed = 0; - for (unsigned int v = 0; v < iNumIndices;++v) { - unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v]; - - // check whether we do already have this vertex - if (0xFFFFFFFF == avWasCopied[iIndex]) { - iNeed++; - } - } - if (pcMesh->mNumVertices + iNeed > iOutVertexNum) { - // don't use this face - break; - } - - vFaces.push_back(aiFace()); - aiFace& rFace = vFaces.back(); - - // setup face type and number of indices - rFace.mNumIndices = iNumIndices; - rFace.mIndices = new unsigned int[iNumIndices]; - - // need to update the output primitive types - switch (rFace.mNumIndices) { - case 1: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; - case 2: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; - case 3: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - default: - pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - } - - // and copy the contents of the old array, offset by current base - for (unsigned int v = 0; v < iNumIndices;++v) { - unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v]; - - // check whether we do already have this vertex - if (0xFFFFFFFF != avWasCopied[iIndex]) { - rFace.mIndices[v] = avWasCopied[iIndex]; - continue; - } - - // copy positions - pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]); - - // copy normals - if (pMesh->HasNormals()) { - pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]); - } - - // copy tangents/bitangents - if (pMesh->HasTangentsAndBitangents()) { - pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]); - pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]); - } - - // texture coordinates - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { - if (pMesh->HasTextureCoords( c)) { - pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex]; - } - } - // vertex colors - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) { - if (pMesh->HasVertexColors( c)) { - pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex]; - } - } - // check whether we have bone weights assigned to this vertex - rFace.mIndices[v] = pcMesh->mNumVertices; - if (avPerVertexWeights) { - VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ]; - if( !table.empty() ) { - for (VertexWeightTable::const_iterator iter = table.begin(); - iter != table.end();++iter) { - // allocate the bone weight array if necessary - BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first]; - if (nullptr == pcWeightList) { - pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList()); - } - pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second)); - } - } - } - - avWasCopied[iIndex] = pcMesh->mNumVertices; - pcMesh->mNumVertices++; - } - ++iBase; - if(pcMesh->mNumVertices == iOutVertexNum) { - // break here. The face is only added if it was complete - break; - } - } - - // check which bones we'll need to create for this submesh - if (pMesh->HasBones()) { - aiBone** ppCurrent = pcMesh->mBones; - for (unsigned int k = 0; k < pMesh->mNumBones;++k) { - // check whether the bone is existing - BoneWeightList* pcWeightList; - if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k])) { - aiBone* pcOldBone = pMesh->mBones[k]; - aiBone* pcOut( nullptr ); - *ppCurrent++ = pcOut = new aiBone(); - pcOut->mName = aiString(pcOldBone->mName); - pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix; - pcOut->mNumWeights = (unsigned int)pcWeightList->size(); - pcOut->mWeights = new aiVertexWeight[pcOut->mNumWeights]; - - // copy the vertex weights - ::memcpy(pcOut->mWeights,&pcWeightList->operator[](0), - pcOut->mNumWeights * sizeof(aiVertexWeight)); - - // delete the temporary bone weight list - delete pcWeightList; - pcMesh->mNumBones++; - } - } - } - - // copy the face list to the mesh - pcMesh->mFaces = new aiFace[vFaces.size()]; - pcMesh->mNumFaces = (unsigned int)vFaces.size(); - - for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) { - pcMesh->mFaces[p] = vFaces[p]; - } - - // add the newly created mesh to the list - avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a)); - - if (iBase == pMesh->mNumFaces) { - // have all faces ... finish the outer loop, too - break; - } - } - - // delete the per-vertex weight list again - delete[] avPerVertexWeights; - - // now delete the old mesh data - delete pMesh; - return; - } - avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a)); -} diff --git a/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h deleted file mode 100644 index 3f90576ea9..0000000000 --- a/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to split large meshes into sub-meshes - */ -#ifndef AI_SPLITLARGEMESHES_H_INC -#define AI_SPLITLARGEMESHES_H_INC - -#include <vector> -#include "Common/BaseProcess.h" - -#include <assimp/mesh.h> -#include <assimp/scene.h> - -// Forward declarations -class SplitLargeMeshesTest; - -namespace Assimp { - -class SplitLargeMeshesProcess_Triangle; -class SplitLargeMeshesProcess_Vertex; - -// NOTE: If you change these limits, don't forget to change the -// corresponding values in all Assimp ports - -// ********************************************************** -// Java: ConfigProperty.java, -// ConfigProperty.DEFAULT_VERTEX_SPLIT_LIMIT -// ConfigProperty.DEFAULT_TRIANGLE_SPLIT_LIMIT -// ********************************************************** - -// default limit for vertices -#if (!defined AI_SLM_DEFAULT_MAX_VERTICES) -# define AI_SLM_DEFAULT_MAX_VERTICES 1000000 -#endif - -// default limit for triangles -#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES) -# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000 -#endif - -// --------------------------------------------------------------------------- -/** Post-processing filter to split large meshes into sub-meshes - * - * Applied BEFORE the JoinVertices-Step occurs. - * Returns NON-UNIQUE vertices, splits by triangle number. -*/ -class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess -{ - friend class SplitLargeMeshesProcess_Vertex; - -public: - - SplitLargeMeshesProcess_Triangle(); - ~SplitLargeMeshesProcess_Triangle(); - -public: - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag. - * @param pFlags The processing flags the importer was called with. A - * bitwise combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, - * false if not. - */ - bool IsActive( unsigned int pFlags) const; - - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - virtual void SetupProperties(const Importer* pImp); - - - //! Set the split limit - needed for unit testing - inline void SetLimit(unsigned int l) - {LIMIT = l;} - - //! Get the split limit - inline unsigned int GetLimit() const - {return LIMIT;} - -public: - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - //! Apply the algorithm to a given mesh - void SplitMesh (unsigned int a, aiMesh* pcMesh, - std::vector<std::pair<aiMesh*, unsigned int> >& avList); - - // ------------------------------------------------------------------- - //! Update a node in the asset after a few of its meshes - //! have been split - static void UpdateNode(aiNode* pcNode, - const std::vector<std::pair<aiMesh*, unsigned int> >& avList); - -public: - //! Triangle limit - unsigned int LIMIT; -}; - - -// --------------------------------------------------------------------------- -/** Post-processing filter to split large meshes into sub-meshes - * - * Applied AFTER the JoinVertices-Step occurs. - * Returns UNIQUE vertices, splits by vertex number. -*/ -class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess -{ -public: - - SplitLargeMeshesProcess_Vertex(); - ~SplitLargeMeshesProcess_Vertex(); - -public: - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Called prior to ExecuteOnScene(). - * The function is a request to the process to update its configuration - * basing on the Importer's configuration property list. - */ - virtual void SetupProperties(const Importer* pImp); - - - //! Set the split limit - needed for unit testing - inline void SetLimit(unsigned int l) - {LIMIT = l;} - - //! Get the split limit - inline unsigned int GetLimit() const - {return LIMIT;} - -public: - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - //! Apply the algorithm to a given mesh - void SplitMesh (unsigned int a, aiMesh* pcMesh, - std::vector<std::pair<aiMesh*, unsigned int> >& avList); - - // NOTE: Reuse SplitLargeMeshesProcess_Triangle::UpdateNode() - -public: - //! Triangle limit - unsigned int LIMIT; -}; - -} // end of namespace Assimp - -#endif // !!AI_SPLITLARGEMESHES_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp b/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp deleted file mode 100644 index 8ae2ba7218..0000000000 --- a/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp +++ /dev/null @@ -1,566 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file A helper class that processes texture transformations */ - - - -#include <assimp/Importer.hpp> -#include <assimp/postprocess.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/scene.h> - -#include "TextureTransform.h" -#include <assimp/StringUtils.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -TextureTransformStep::TextureTransformStep() : - configFlags() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -TextureTransformStep::~TextureTransformStep() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool TextureTransformStep::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_TransformUVCoords) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Setup properties -void TextureTransformStep::SetupProperties(const Importer* pImp) -{ - configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL); -} - -// ------------------------------------------------------------------------------------------------ -void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info) -{ - /* This function tries to simplify the input UV transformation. - * That's very important as it allows us to reduce the number - * of output UV channels. The order in which the transformations - * are applied is - as always - scaling, rotation, translation. - */ - - char szTemp[512]; - int rounded = 0; - - - /* Optimize the rotation angle. That's slightly difficult as - * we have an inprecise floating-point number (when comparing - * UV transformations we'll take that into account by using - * an epsilon of 5 degrees). If there is a rotation value, we can't - * perform any further optimizations. - */ - if (info.mRotation) - { - float out = info.mRotation; - if ((rounded = static_cast<int>((info.mRotation / static_cast<float>(AI_MATH_TWO_PI))))) - { - out -= rounded * static_cast<float>(AI_MATH_PI); - ASSIMP_LOG_INFO_F("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out); - } - - // Next step - convert negative rotation angles to positives - if (out < 0.f) - out = (float)AI_MATH_TWO_PI * 2 + out; - - info.mRotation = out; - return; - } - - - /* Optimize UV translation in the U direction. To determine whether - * or not we can optimize we need to look at the requested mapping - * type (e.g. if mirroring is active there IS a difference between - * offset 2 and 3) - */ - if ((rounded = (int)info.mTranslation.x)) { - float out = 0.0f; - szTemp[0] = 0; - if (aiTextureMapMode_Wrap == info.mapU) { - // Wrap - simple take the fraction of the field - out = info.mTranslation.x-(float)rounded; - ai_snprintf(szTemp, 512, "[w] UV U offset %f can be simplified to %f", info.mTranslation.x, out); - } - else if (aiTextureMapMode_Mirror == info.mapU && 1 != rounded) { - // Mirror - if (rounded % 2) - rounded--; - out = info.mTranslation.x-(float)rounded; - - ai_snprintf(szTemp,512,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out); - } - else if (aiTextureMapMode_Clamp == info.mapU || aiTextureMapMode_Decal == info.mapU) { - // Clamp - translations beyond 1,1 are senseless - ai_snprintf(szTemp,512,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x); - - out = 1.f; - } - if (szTemp[0]) { - ASSIMP_LOG_INFO(szTemp); - info.mTranslation.x = out; - } - } - - /* Optimize UV translation in the V direction. To determine whether - * or not we can optimize we need to look at the requested mapping - * type (e.g. if mirroring is active there IS a difference between - * offset 2 and 3) - */ - if ((rounded = (int)info.mTranslation.y)) { - float out = 0.0f; - szTemp[0] = 0; - if (aiTextureMapMode_Wrap == info.mapV) { - // Wrap - simple take the fraction of the field - out = info.mTranslation.y-(float)rounded; - ::ai_snprintf(szTemp,512,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out); - } - else if (aiTextureMapMode_Mirror == info.mapV && 1 != rounded) { - // Mirror - if (rounded % 2) - rounded--; - out = info.mTranslation.x-(float)rounded; - - ::ai_snprintf(szTemp,512,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out); - } - else if (aiTextureMapMode_Clamp == info.mapV || aiTextureMapMode_Decal == info.mapV) { - // Clamp - translations beyond 1,1 are senseless - ::ai_snprintf(szTemp,512,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y); - - out = 1.f; - } - if (szTemp[0]) { - ASSIMP_LOG_INFO(szTemp); - info.mTranslation.y = out; - } - } - return; -} - -// ------------------------------------------------------------------------------------------------ -void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n) -{ - // Don't set if == 0 && wasn't set before - for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) { - const TTUpdateInfo& info = *it; - - if (info.directShortcut) - *info.directShortcut = n; - else if (!n) - { - info.mat->AddProperty<int>((int*)&n,1,AI_MATKEY_UVWSRC(info.semantic,info.index)); - } - } -} - -// ------------------------------------------------------------------------------------------------ -inline const char* MappingModeToChar(aiTextureMapMode map) -{ - if (aiTextureMapMode_Wrap == map) - return "-w"; - - if (aiTextureMapMode_Mirror == map) - return "-m"; - - return "-c"; -} - -// ------------------------------------------------------------------------------------------------ -void TextureTransformStep::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("TransformUVCoordsProcess begin"); - - - /* We build a per-mesh list of texture transformations we'll need - * to apply. To achieve this, we iterate through all materials, - * find all textures and get their transformations and UV indices. - * Then we search for all meshes using this material. - */ - typedef std::list<STransformVecInfo> MeshTrafoList; - std::vector<MeshTrafoList> meshLists(pScene->mNumMeshes); - - for (unsigned int i = 0; i < pScene->mNumMaterials;++i) { - - aiMaterial* mat = pScene->mMaterials[i]; - for (unsigned int a = 0; a < mat->mNumProperties;++a) { - - aiMaterialProperty* prop = mat->mProperties[a]; - if (!::strcmp( prop->mKey.data, "$tex.file")) { - STransformVecInfo info; - - // Setup a shortcut structure to allow for a fast updating - // of the UV index later - TTUpdateInfo update; - update.mat = (aiMaterial*) mat; - update.semantic = prop->mSemantic; - update.index = prop->mIndex; - - // Get textured properties and transform - for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2) { - aiMaterialProperty* prop2 = mat->mProperties[a2]; - if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) { - continue; - } - - if ( !::strcmp( prop2->mKey.data, "$tex.uvwsrc")) { - info.uvIndex = *((int*)prop2->mData); - - // Store a direct pointer for later use - update.directShortcut = (unsigned int*) prop2->mData; - } - - else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodeu")) { - info.mapU = *((aiTextureMapMode*)prop2->mData); - } - else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodev")) { - info.mapV = *((aiTextureMapMode*)prop2->mData); - } - else if ( !::strcmp( prop2->mKey.data, "$tex.uvtrafo")) { - // ValidateDS should check this - ai_assert(prop2->mDataLength >= 20); - ::memcpy(&info.mTranslation.x,prop2->mData,sizeof(float)*5); - - // Directly remove this property from the list - mat->mNumProperties--; - for (unsigned int a3 = a2; a3 < mat->mNumProperties;++a3) { - mat->mProperties[a3] = mat->mProperties[a3+1]; - } - - delete prop2; - - // Warn: could be an underflow, but this does not invoke undefined behaviour - --a2; - } - } - - // Find out which transformations are to be evaluated - if (!(configFlags & AI_UVTRAFO_ROTATION)) { - info.mRotation = 0.f; - } - if (!(configFlags & AI_UVTRAFO_SCALING)) { - info.mScaling = aiVector2D(1.f,1.f); - } - if (!(configFlags & AI_UVTRAFO_TRANSLATION)) { - info.mTranslation = aiVector2D(0.f,0.f); - } - - // Do some preprocessing - PreProcessUVTransform(info); - info.uvIndex = std::min(info.uvIndex,AI_MAX_NUMBER_OF_TEXTURECOORDS -1u); - - // Find out whether this material is used by more than - // one mesh. This will make our task much, much more difficult! - unsigned int cnt = 0; - for (unsigned int n = 0; n < pScene->mNumMeshes;++n) { - if (pScene->mMeshes[n]->mMaterialIndex == i) - ++cnt; - } - - if (!cnt) - continue; - else if (1 != cnt) { - // This material is referenced by more than one mesh! - // So we need to make sure the UV index for the texture - // is identical for each of it ... - info.lockedPos = AI_TT_UV_IDX_LOCK_TBD; - } - - // Get all corresponding meshes - for (unsigned int n = 0; n < pScene->mNumMeshes;++n) { - aiMesh* mesh = pScene->mMeshes[n]; - if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0]) - continue; - - unsigned int uv = info.uvIndex; - if (!mesh->mTextureCoords[uv]) { - // If the requested UV index is not available, take the first one instead. - uv = 0; - } - - if (mesh->mNumUVComponents[info.uvIndex] >= 3){ - ASSIMP_LOG_WARN("UV transformations on 3D mapping channels are not supported"); - continue; - } - - MeshTrafoList::iterator it; - - // Check whether we have this transform setup already - for (it = meshLists[n].begin();it != meshLists[n].end(); ++it) { - - if ((*it) == info && (*it).uvIndex == uv) { - (*it).updateList.push_back(update); - break; - } - } - - if (it == meshLists[n].end()) { - meshLists[n].push_back(info); - meshLists[n].back().uvIndex = uv; - meshLists[n].back().updateList.push_back(update); - } - } - } - } - } - - char buffer[1024]; // should be sufficiently large - unsigned int outChannels = 0, inChannels = 0, transformedChannels = 0; - - // Now process all meshes. Important: we don't remove unreferenced UV channels. - // This is a job for the RemoveUnreferencedData-Step. - for (unsigned int q = 0; q < pScene->mNumMeshes;++q) { - - aiMesh* mesh = pScene->mMeshes[q]; - MeshTrafoList& trafo = meshLists[q]; - - inChannels += mesh->GetNumUVChannels(); - - if (!mesh->mTextureCoords[0] || trafo.empty() || (trafo.size() == 1 && trafo.begin()->IsUntransformed())) { - outChannels += mesh->GetNumUVChannels(); - continue; - } - - // Move untransformed UV channels to the first position in the list .... - // except if we need a new locked index which should be as small as possible - bool veto = false, need = false; - unsigned int cnt = 0; - unsigned int untransformed = 0; - - MeshTrafoList::iterator it,it2; - for (it = trafo.begin();it != trafo.end(); ++it,++cnt) { - - if (!(*it).IsUntransformed()) { - need = true; - } - - if ((*it).lockedPos == AI_TT_UV_IDX_LOCK_TBD) { - // Lock this index and make sure it won't be changed - (*it).lockedPos = cnt; - veto = true; - continue; - } - - if (!veto && it != trafo.begin() && (*it).IsUntransformed()) { - for (it2 = trafo.begin();it2 != it; ++it2) { - if (!(*it2).IsUntransformed()) - break; - } - trafo.insert(it2,*it); - trafo.erase(it); - break; - } - } - if (!need) - continue; - - // Find all that are not at their 'locked' position and move them to it. - // Conflicts are possible but quite unlikely. - cnt = 0; - for (it = trafo.begin();it != trafo.end(); ++it,++cnt) { - if ((*it).lockedPos != AI_TT_UV_IDX_LOCK_NONE && (*it).lockedPos != cnt) { - it2 = trafo.begin();unsigned int t = 0; - while (t != (*it).lockedPos) - ++it2; - - if ((*it2).lockedPos != AI_TT_UV_IDX_LOCK_NONE) { - ASSIMP_LOG_ERROR("Channel mismatch, can't compute all transformations properly [design bug]"); - continue; - } - - std::swap(*it2,*it); - if ((*it).lockedPos == untransformed) - untransformed = cnt; - } - } - - // ... and add dummies for all unreferenced channels - // at the end of the list - bool ref[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) - ref[n] = (!mesh->mTextureCoords[n] ? true : false); - - for (it = trafo.begin();it != trafo.end(); ++it) - ref[(*it).uvIndex] = true; - - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (ref[n]) - continue; - trafo.push_back(STransformVecInfo()); - trafo.back().uvIndex = n; - } - - // Then check whether this list breaks the channel limit. - // The unimportant ones are at the end of the list, so - // it shouldn't be too worse if we remove them. - unsigned int size = (unsigned int)trafo.size(); - if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) { - - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR_F(static_cast<unsigned int>(trafo.size()), " UV channels required but just ", - AI_MAX_NUMBER_OF_TEXTURECOORDS, " available"); - } - size = AI_MAX_NUMBER_OF_TEXTURECOORDS; - } - - - aiVector3D* old[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) - old[n] = mesh->mTextureCoords[n]; - - // Now continue and generate the output channels. Channels - // that we're not going to need later can be overridden. - it = trafo.begin(); - for (unsigned int n = 0; n < trafo.size();++n,++it) { - - if (n >= size) { - // Try to use an untransformed channel for all channels we threw over board - UpdateUVIndex((*it).updateList,untransformed); - continue; - } - - outChannels++; - - // Write to the log - if (!DefaultLogger::isNullLogger()) { - ::ai_snprintf(buffer,1024,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s", - q,n, - (*it).mTranslation.x, - (*it).mTranslation.y, - (*it).mScaling.x, - (*it).mScaling.y, - AI_RAD_TO_DEG( (*it).mRotation), - MappingModeToChar ((*it).mapU), - MappingModeToChar ((*it).mapV)); - - ASSIMP_LOG_INFO(buffer); - } - - // Check whether we need a new buffer here - if (mesh->mTextureCoords[n]) { - - it2 = it;++it2; - for (unsigned int m = n+1; m < size;++m, ++it2) { - - if ((*it2).uvIndex == n){ - it2 = trafo.begin(); - break; - } - } - if (it2 == trafo.begin()){ - mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; - } - } - else mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; - - aiVector3D* src = old[(*it).uvIndex]; - aiVector3D* dest, *end; - dest = mesh->mTextureCoords[n]; - - ai_assert(NULL != src); - - // Copy the data to the destination array - if (dest != src) - ::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices); - - end = dest + mesh->mNumVertices; - - // Build a transformation matrix and transform all UV coords with it - if (!(*it).IsUntransformed()) { - const aiVector2D& trl = (*it).mTranslation; - const aiVector2D& scl = (*it).mScaling; - - // fixme: simplify .. - ++transformedChannels; - aiMatrix3x3 matrix; - - aiMatrix3x3 m2,m3,m4,m5; - - m4.a1 = scl.x; - m4.b2 = scl.y; - - m2.a3 = m2.b3 = 0.5f; - m3.a3 = m3.b3 = -0.5f; - - if ((*it).mRotation > AI_TT_ROTATION_EPSILON ) - aiMatrix3x3::RotationZ((*it).mRotation,matrix); - - m5.a3 += trl.x; m5.b3 += trl.y; - matrix = m2 * m4 * matrix * m3 * m5; - - for (src = dest; src != end; ++src) { /* manual homogenious divide */ - src->z = 1.f; - *src = matrix * *src; - src->x /= src->z; - src->y /= src->z; - src->z = 0.f; - } - } - - // Update all UV indices - UpdateUVIndex((*it).updateList,n); - } - } - - // Print some detailed statistics into the log - if (!DefaultLogger::isNullLogger()) { - - if (transformedChannels) { - ASSIMP_LOG_INFO_F("TransformUVCoordsProcess end: ", outChannels, " output channels (in: ", inChannels, ", modified: ", transformedChannels,")"); - } else { - ASSIMP_LOG_DEBUG("TransformUVCoordsProcess finished"); - } - } -} - - diff --git a/thirdparty/assimp/code/PostProcessing/TextureTransform.h b/thirdparty/assimp/code/PostProcessing/TextureTransform.h deleted file mode 100644 index 2a5d623d7f..0000000000 --- a/thirdparty/assimp/code/PostProcessing/TextureTransform.h +++ /dev/null @@ -1,232 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Definition of a helper step that processes texture transformations */ -#ifndef AI_TEXTURE_TRANSFORM_H_INCLUDED -#define AI_TEXTURE_TRANSFORM_H_INCLUDED - -#include <assimp/BaseImporter.h> -#include "Common/BaseProcess.h" - -#include <assimp/material.h> -#include <list> - -struct aiNode; -struct aiMaterial; - -namespace Assimp { - -#define AI_TT_UV_IDX_LOCK_TBD 0xffffffff -#define AI_TT_UV_IDX_LOCK_NONE 0xeeeeeeee - - -#define AI_TT_ROTATION_EPSILON ((float)AI_DEG_TO_RAD(0.5)) - -// --------------------------------------------------------------------------- -/** Small helper structure representing a shortcut into the material list - * to be able to update some values quickly. -*/ -struct TTUpdateInfo { - TTUpdateInfo() AI_NO_EXCEPT - : directShortcut(nullptr) - , mat(nullptr) - , semantic(0) - , index(0) { - // empty - } - - //! Direct shortcut, if available - unsigned int* directShortcut; - - //! Material - aiMaterial *mat; - - //! Texture type and index - unsigned int semantic, index; -}; - - -// --------------------------------------------------------------------------- -/** Helper class representing texture coordinate transformations -*/ -struct STransformVecInfo : public aiUVTransform { - STransformVecInfo() AI_NO_EXCEPT - : uvIndex(0) - , mapU(aiTextureMapMode_Wrap) - , mapV(aiTextureMapMode_Wrap) - , lockedPos(AI_TT_UV_IDX_LOCK_NONE) { - // empty - } - - //! Source texture coordinate index - unsigned int uvIndex; - - //! Texture mapping mode in the u, v direction - aiTextureMapMode mapU,mapV; - - //! Locked destination UV index - //! AI_TT_UV_IDX_LOCK_TBD - to be determined - //! AI_TT_UV_IDX_LOCK_NONE - none (default) - unsigned int lockedPos; - - //! Update info - shortcuts into all materials - //! that are referencing this transform setup - std::list<TTUpdateInfo> updateList; - - - // ------------------------------------------------------------------- - /** Compare two transform setups - */ - inline bool operator== (const STransformVecInfo& other) const - { - // We use a small epsilon here - const static float epsilon = 0.05f; - - if (std::fabs( mTranslation.x - other.mTranslation.x ) > epsilon || - std::fabs( mTranslation.y - other.mTranslation.y ) > epsilon) - { - return false; - } - - if (std::fabs( mScaling.x - other.mScaling.x ) > epsilon || - std::fabs( mScaling.y - other.mScaling.y ) > epsilon) - { - return false; - } - - if (std::fabs( mRotation - other.mRotation) > epsilon) - { - return false; - } - return true; - } - - inline bool operator!= (const STransformVecInfo& other) const - { - return !(*this == other); - } - - - // ------------------------------------------------------------------- - /** Returns whether this is an untransformed texture coordinate set - */ - inline bool IsUntransformed() const - { - return (1.0f == mScaling.x && 1.f == mScaling.y && - !mTranslation.x && !mTranslation.y && - mRotation < AI_TT_ROTATION_EPSILON); - } - - // ------------------------------------------------------------------- - /** Build a 3x3 matrix from the transformations - */ - inline void GetMatrix(aiMatrix3x3& mOut) - { - mOut = aiMatrix3x3(); - - if (1.0f != mScaling.x || 1.0f != mScaling.y) - { - aiMatrix3x3 mScale; - mScale.a1 = mScaling.x; - mScale.b2 = mScaling.y; - mOut = mScale; - } - if (mRotation) - { - aiMatrix3x3 mRot; - mRot.a1 = mRot.b2 = std::cos(mRotation); - mRot.a2 = mRot.b1 = std::sin(mRotation); - mRot.a2 = -mRot.a2; - mOut *= mRot; - } - if (mTranslation.x || mTranslation.y) - { - aiMatrix3x3 mTrans; - mTrans.a3 = mTranslation.x; - mTrans.b3 = mTranslation.y; - mOut *= mTrans; - } - } -}; - - -// --------------------------------------------------------------------------- -/** Helper step to compute final UV coordinate sets if there are scalings - * or rotations in the original data read from the file. -*/ -class TextureTransformStep : public BaseProcess -{ -public: - - TextureTransformStep(); - ~TextureTransformStep(); - -public: - - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - void SetupProperties(const Importer* pImp); - - -protected: - - - // ------------------------------------------------------------------- - /** Preprocess a specific UV transformation setup - * - * @param info Transformation setup to be preprocessed. - */ - void PreProcessUVTransform(STransformVecInfo& info); - -private: - - unsigned int configFlags; -}; - -} - -#endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED diff --git a/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp deleted file mode 100644 index 1040836bbe..0000000000 --- a/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file TriangulateProcess.cpp - * @brief Implementation of the post processing step to split up - * all faces with more than three indices into triangles. - * - * - * The triangulation algorithm will handle concave or convex polygons. - * Self-intersecting or non-planar polygons are not rejected, but - * they're probably not triangulated correctly. - * - * DEBUG SWITCHES - do not enable any of them in release builds: - * - * AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING - * - generates vertex colors to represent the face winding order. - * the first vertex of a polygon becomes red, the last blue. - * AI_BUILD_TRIANGULATE_DEBUG_POLYS - * - dump all polygons and their triangulation sequences to - * a file - */ -#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS - -#include "PostProcessing/TriangulateProcess.h" -#include "PostProcessing/ProcessHelper.h" -#include "Common/PolyTools.h" - -#include <memory> - -//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING -//#define AI_BUILD_TRIANGULATE_DEBUG_POLYS - -#define POLY_GRID_Y 40 -#define POLY_GRID_X 70 -#define POLY_GRID_XPAD 20 -#define POLY_OUTPUT_FILE "assimp_polygons_debug.txt" - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -TriangulateProcess::TriangulateProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -TriangulateProcess::~TriangulateProcess() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool TriangulateProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_Triangulate) != 0; -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void TriangulateProcess::Execute( aiScene* pScene) -{ - ASSIMP_LOG_DEBUG("TriangulateProcess begin"); - - bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) - { - if (pScene->mMeshes[ a ]) { - if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) { - bHas = true; - } - } - } - if ( bHas ) { - ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." ); - } else { - ASSIMP_LOG_DEBUG( "TriangulateProcess finished. There was nothing to be done." ); - } -} - -// ------------------------------------------------------------------------------------------------ -// Triangulates the given mesh. -bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) -{ - // Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases - if (!pMesh->mPrimitiveTypes) { - bool bNeed = false; - - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - const aiFace& face = pMesh->mFaces[a]; - - if( face.mNumIndices != 3) { - bNeed = true; - } - } - if (!bNeed) - return false; - } - else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) { - return false; - } - - // Find out how many output faces we'll get - unsigned int numOut = 0, max_out = 0; - bool get_normals = true; - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - aiFace& face = pMesh->mFaces[a]; - if (face.mNumIndices <= 4) { - get_normals = false; - } - if( face.mNumIndices <= 3) { - numOut++; - - } - else { - numOut += face.mNumIndices-2; - max_out = std::max(max_out,face.mNumIndices); - } - } - - // Just another check whether aiMesh::mPrimitiveTypes is correct - ai_assert(numOut != pMesh->mNumFaces); - - aiVector3D* nor_out = NULL; - - // if we don't have normals yet, but expect them to be a cheap side - // product of triangulation anyway, allocate storage for them. - if (!pMesh->mNormals && get_normals) { - // XXX need a mechanism to inform the GenVertexNormals process to treat these normals as preprocessed per-face normals - // nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - } - - // the output mesh will contain triangles, but no polys anymore - pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON; - - aiFace* out = new aiFace[numOut](), *curOut = out; - std::vector<aiVector3D> temp_verts3d(max_out+2); /* temporary storage for vertices */ - std::vector<aiVector2D> temp_verts(max_out+2); - - // Apply vertex colors to represent the face winding? -#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING - if (!pMesh->mColors[0]) - pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices]; - else - new(pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices]; - - aiColor4D* clr = pMesh->mColors[0]; -#endif - -#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - FILE* fout = fopen(POLY_OUTPUT_FILE,"a"); -#endif - - const aiVector3D* verts = pMesh->mVertices; - - // use std::unique_ptr to avoid slow std::vector<bool> specialiations - std::unique_ptr<bool[]> done(new bool[max_out]); - for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { - aiFace& face = pMesh->mFaces[a]; - - unsigned int* idx = face.mIndices; - int num = (int)face.mNumIndices, ear = 0, tmp, prev = num-1, next = 0, max = num; - - // Apply vertex colors to represent the face winding? -#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING - for (unsigned int i = 0; i < face.mNumIndices; ++i) { - aiColor4D& c = clr[idx[i]]; - c.r = (i+1) / (float)max; - c.b = 1.f - c.r; - } -#endif - - aiFace* const last_face = curOut; - - // if it's a simple point,line or triangle: just copy it - if( face.mNumIndices <= 3) - { - aiFace& nface = *curOut++; - nface.mNumIndices = face.mNumIndices; - nface.mIndices = face.mIndices; - - face.mIndices = NULL; - continue; - } - // optimized code for quadrilaterals - else if ( face.mNumIndices == 4) { - - // quads can have at maximum one concave vertex. Determine - // this vertex (if it exists) and start tri-fanning from - // it. - unsigned int start_vertex = 0; - for (unsigned int i = 0; i < 4; ++i) { - const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]]; - const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]]; - const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]]; - - const aiVector3D& v = verts[face.mIndices[i]]; - - aiVector3D left = (v0-v); - aiVector3D diag = (v1-v); - aiVector3D right = (v2-v); - - left.Normalize(); - diag.Normalize(); - right.Normalize(); - - const float angle = std::acos(left*diag) + std::acos(right*diag); - if (angle > AI_MATH_PI_F) { - // this is the concave point - start_vertex = i; - break; - } - } - - const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]}; - - aiFace& nface = *curOut++; - nface.mNumIndices = 3; - nface.mIndices = face.mIndices; - - nface.mIndices[0] = temp[start_vertex]; - nface.mIndices[1] = temp[(start_vertex + 1) % 4]; - nface.mIndices[2] = temp[(start_vertex + 2) % 4]; - - aiFace& sface = *curOut++; - sface.mNumIndices = 3; - sface.mIndices = new unsigned int[3]; - - sface.mIndices[0] = temp[start_vertex]; - sface.mIndices[1] = temp[(start_vertex + 2) % 4]; - sface.mIndices[2] = temp[(start_vertex + 3) % 4]; - - // prevent double deletion of the indices field - face.mIndices = NULL; - continue; - } - else - { - // A polygon with more than 3 vertices can be either concave or convex. - // Usually everything we're getting is convex and we could easily - // triangulate by tri-fanning. However, LightWave is probably the only - // modeling suite to make extensive use of highly concave, monster polygons ... - // so we need to apply the full 'ear cutting' algorithm to get it right. - - // RERQUIREMENT: polygon is expected to be simple and *nearly* planar. - // We project it onto a plane to get a 2d triangle. - - // Collect all vertices of of the polygon. - for (tmp = 0; tmp < max; ++tmp) { - temp_verts3d[tmp] = verts[idx[tmp]]; - } - - // Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh - aiVector3D n; - NewellNormal<3,3,3>(n,max,&temp_verts3d.front().x,&temp_verts3d.front().y,&temp_verts3d.front().z); - if (nor_out) { - for (tmp = 0; tmp < max; ++tmp) - nor_out[idx[tmp]] = n; - } - - // Select largest normal coordinate to ignore for projection - const float ax = (n.x>0 ? n.x : -n.x); - const float ay = (n.y>0 ? n.y : -n.y); - const float az = (n.z>0 ? n.z : -n.z); - - unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */ - float inv = n.z; - if (ax > ay) { - if (ax > az) { /* no x coord. projection to yz */ - ac = 1; bc = 2; - inv = n.x; - } - } - else if (ay > az) { /* no y coord. projection to zy */ - ac = 2; bc = 0; - inv = n.y; - } - - // Swap projection axes to take the negated projection vector into account - if (inv < 0.f) { - std::swap(ac,bc); - } - - for (tmp =0; tmp < max; ++tmp) { - temp_verts[tmp].x = verts[idx[tmp]][ac]; - temp_verts[tmp].y = verts[idx[tmp]][bc]; - done[tmp] = false; - } - -#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - // plot the plane onto which we mapped the polygon to a 2D ASCII pic - aiVector2D bmin,bmax; - ArrayBounds(&temp_verts[0],max,bmin,bmax); - - char grid[POLY_GRID_Y][POLY_GRID_X+POLY_GRID_XPAD]; - std::fill_n((char*)grid,POLY_GRID_Y*(POLY_GRID_X+POLY_GRID_XPAD),' '); - - for (int i =0; i < max; ++i) { - const aiVector2D& v = (temp_verts[i] - bmin) / (bmax-bmin); - const size_t x = static_cast<size_t>(v.x*(POLY_GRID_X-1)), y = static_cast<size_t>(v.y*(POLY_GRID_Y-1)); - char* loc = grid[y]+x; - if (grid[y][x] != ' ') { - for(;*loc != ' '; ++loc); - *loc++ = '_'; - } - *(loc+::ai_snprintf(loc, POLY_GRID_XPAD,"%i",i)) = ' '; - } - - - for(size_t y = 0; y < POLY_GRID_Y; ++y) { - grid[y][POLY_GRID_X+POLY_GRID_XPAD-1] = '\0'; - fprintf(fout,"%s\n",grid[y]); - } - - fprintf(fout,"\ntriangulation sequence: "); -#endif - - // - // FIXME: currently this is the slow O(kn) variant with a worst case - // complexity of O(n^2) (I think). Can be done in O(n). - while (num > 3) { - - // Find the next ear of the polygon - int num_found = 0; - for (ear = next;;prev = ear,ear = next) { - - // break after we looped two times without a positive match - for (next=ear+1;done[(next>=max?next=0:next)];++next); - if (next < ear) { - if (++num_found == 2) { - break; - } - } - const aiVector2D* pnt1 = &temp_verts[ear], - *pnt0 = &temp_verts[prev], - *pnt2 = &temp_verts[next]; - - // Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1. - if (OnLeftSideOfLine2D(*pnt0,*pnt2,*pnt1)) { - continue; - } - - // and no other point may be contained in this triangle - for ( tmp = 0; tmp < max; ++tmp) { - - // We need to compare the actual values because it's possible that multiple indexes in - // the polygon are referring to the same position. concave_polygon.obj is a sample - // - // FIXME: Use 'epsiloned' comparisons instead? Due to numeric inaccuracies in - // PointInTriangle() I'm guessing that it's actually possible to construct - // input data that would cause us to end up with no ears. The problem is, - // which epsilon? If we chose a too large value, we'd get wrong results - const aiVector2D& vtmp = temp_verts[tmp]; - if ( vtmp != *pnt1 && vtmp != *pnt2 && vtmp != *pnt0 && PointInTriangle2D(*pnt0,*pnt1,*pnt2,vtmp)) { - break; - } - } - if (tmp != max) { - continue; - } - - // this vertex is an ear - break; - } - if (num_found == 2) { - - // Due to the 'two ear theorem', every simple polygon with more than three points must - // have 2 'ears'. Here's definitely something wrong ... but we don't give up yet. - // - - // Instead we're continuing with the standard tri-fanning algorithm which we'd - // use if we had only convex polygons. That's life. - ASSIMP_LOG_ERROR("Failed to triangulate polygon (no ear found). Probably not a simple polygon?"); - -#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - fprintf(fout,"critical error here, no ear found! "); -#endif - num = 0; - break; - - curOut -= (max-num); /* undo all previous work */ - for (tmp = 0; tmp < max-2; ++tmp) { - aiFace& nface = *curOut++; - - nface.mNumIndices = 3; - if (!nface.mIndices) - nface.mIndices = new unsigned int[3]; - - nface.mIndices[0] = 0; - nface.mIndices[1] = tmp+1; - nface.mIndices[2] = tmp+2; - - } - num = 0; - break; - } - - aiFace& nface = *curOut++; - nface.mNumIndices = 3; - - if (!nface.mIndices) { - nface.mIndices = new unsigned int[3]; - } - - // setup indices for the new triangle ... - nface.mIndices[0] = prev; - nface.mIndices[1] = ear; - nface.mIndices[2] = next; - - // exclude the ear from most further processing - done[ear] = true; - --num; - } - if (num > 0) { - // We have three indices forming the last 'ear' remaining. Collect them. - aiFace& nface = *curOut++; - nface.mNumIndices = 3; - if (!nface.mIndices) { - nface.mIndices = new unsigned int[3]; - } - - for (tmp = 0; done[tmp]; ++tmp); - nface.mIndices[0] = tmp; - - for (++tmp; done[tmp]; ++tmp); - nface.mIndices[1] = tmp; - - for (++tmp; done[tmp]; ++tmp); - nface.mIndices[2] = tmp; - - } - } - -#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - - for(aiFace* f = last_face; f != curOut; ++f) { - unsigned int* i = f->mIndices; - fprintf(fout," (%i %i %i)",i[0],i[1],i[2]); - } - - fprintf(fout,"\n*********************************************************************\n"); - fflush(fout); - -#endif - - for(aiFace* f = last_face; f != curOut; ) { - unsigned int* i = f->mIndices; - - // drop dumb 0-area triangles - deactivated for now: - //FindDegenerates post processing step can do the same thing - //if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) { - // ASSIMP_LOG_DEBUG("Dropping triangle with area 0"); - // --curOut; - - // delete[] f->mIndices; - // f->mIndices = nullptr; - - // for(aiFace* ff = f; ff != curOut; ++ff) { - // ff->mNumIndices = (ff+1)->mNumIndices; - // ff->mIndices = (ff+1)->mIndices; - // (ff+1)->mIndices = nullptr; - // } - // continue; - //} - - i[0] = idx[i[0]]; - i[1] = idx[i[1]]; - i[2] = idx[i[2]]; - ++f; - } - - delete[] face.mIndices; - face.mIndices = NULL; - } - -#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS - fclose(fout); -#endif - - // kill the old faces - delete [] pMesh->mFaces; - - // ... and store the new ones - pMesh->mFaces = out; - pMesh->mNumFaces = (unsigned int)(curOut-out); /* not necessarily equal to numOut */ - return true; -} - -#endif // !! ASSIMP_BUILD_NO_TRIANGULATE_PROCESS diff --git a/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h deleted file mode 100644 index 916b5103dd..0000000000 --- a/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a post processing step to triangulate all faces - with more than three vertices. - */ -#ifndef AI_TRIANGULATEPROCESS_H_INC -#define AI_TRIANGULATEPROCESS_H_INC - -#include "Common/BaseProcess.h" - -struct aiMesh; - -class TriangulateProcessTest; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** The TriangulateProcess splits up all faces with more than three indices - * into triangles. You usually want this to happen because the graphics cards - * need their data as triangles. - */ -class ASSIMP_API TriangulateProcess : public BaseProcess { -public: - TriangulateProcess(); - ~TriangulateProcess(); - - // ------------------------------------------------------------------- - /** Returns whether the processing step is present in the given flag field. - * @param pFlags The processing flags the importer was called with. A bitwise - * combination of #aiPostProcessSteps. - * @return true if the process is present in this flag fields, false if not. - */ - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. - * At the moment a process is not supposed to fail. - * @param pScene The imported data to work at. - */ - void Execute( aiScene* pScene); - - // ------------------------------------------------------------------- - /** Triangulates the given mesh. - * @param pMesh The mesh to triangulate. - */ - bool TriangulateMesh( aiMesh* pMesh); -}; - -} // end of namespace Assimp - -#endif // AI_TRIANGULATEPROCESS_H_INC diff --git a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp deleted file mode 100644 index 75d1b6ef78..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp +++ /dev/null @@ -1,1034 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file ValidateDataStructure.cpp - * @brief Implementation of the post processing step to validate - * the data structure returned by Assimp. - */ - -// internal headers -#include "ValidateDataStructure.h" -#include <assimp/BaseImporter.h> -#include <assimp/fast_atof.h> -#include "ProcessHelper.h" -#include <memory> - -// CRT headers -#include <stdarg.h> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -ValidateDSProcess::ValidateDSProcess() : - mScene() -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -ValidateDSProcess::~ValidateDSProcess() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the processing step is present in the given flag field. -bool ValidateDSProcess::IsActive( unsigned int pFlags) const -{ - return (pFlags & aiProcess_ValidateDataStructure) != 0; -} -// ------------------------------------------------------------------------------------------------ -AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...) -{ - ai_assert(NULL != msg); - - va_list args; - va_start(args,msg); - - char szBuffer[3000]; - const int iLen = vsprintf(szBuffer,msg,args); - ai_assert(iLen > 0); - - va_end(args); - - throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen)); -} -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::ReportWarning(const char* msg,...) -{ - ai_assert(NULL != msg); - - va_list args; - va_start(args,msg); - - char szBuffer[3000]; - const int iLen = vsprintf(szBuffer,msg,args); - ai_assert(iLen > 0); - - va_end(args); - ASSIMP_LOG_WARN("Validation warning: " + std::string(szBuffer,iLen)); -} - -// ------------------------------------------------------------------------------------------------ -inline -int HasNameMatch(const aiString& in, aiNode* node) { - int result = (node->mName == in ? 1 : 0 ); - for (unsigned int i = 0; i < node->mNumChildren;++i) { - result += HasNameMatch(in,node->mChildren[i]); - } - return result; -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -void ValidateDSProcess::DoValidation(T** parray, unsigned int size, const char* firstName, const char* secondName) { - // validate all entries - if (size) - { - if (!parray) - { - ReportError("aiScene::%s is NULL (aiScene::%s is %i)", - firstName, secondName, size); - } - for (unsigned int i = 0; i < size;++i) - { - if (!parray[i]) - { - ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)", - firstName,i,secondName,size); - } - Validate(parray[i]); - } - } -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size, - const char* firstName, const char* secondName) -{ - // validate all entries - if (size) - { - if (!parray) { - ReportError("aiScene::%s is NULL (aiScene::%s is %i)", - firstName, secondName, size); - } - for (unsigned int i = 0; i < size;++i) - { - if (!parray[i]) - { - ReportError("aiScene::%s[%u] is NULL (aiScene::%s is %u)", - firstName,i,secondName,size); - } - Validate(parray[i]); - - // check whether there are duplicate names - for (unsigned int a = i+1; a < size;++a) - { - if (parray[i]->mName == parray[a]->mName) - { - ReportError("aiScene::%s[%u] has the same name as " - "aiScene::%s[%u]",firstName, i,secondName, a); - } - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -template <typename T> -inline -void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size, const char* firstName, - const char* secondName) { - // validate all entries - DoValidationEx(array,size,firstName,secondName); - - for (unsigned int i = 0; i < size;++i) { - int res = HasNameMatch(array[i]->mName,mScene->mRootNode); - if (0 == res) { - const std::string name = static_cast<char*>(array[i]->mName.data); - ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)", - firstName,i, name.c_str()); - } else if (1 != res) { - const std::string name = static_cast<char*>(array[i]->mName.data); - ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name", - firstName,i, name.c_str()); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Executes the post processing step on the given imported data. -void ValidateDSProcess::Execute( aiScene* pScene) { - mScene = pScene; - ASSIMP_LOG_DEBUG("ValidateDataStructureProcess begin"); - - // validate the node graph of the scene - Validate(pScene->mRootNode); - - // validate all meshes - if (pScene->mNumMeshes) { - DoValidation(pScene->mMeshes,pScene->mNumMeshes,"mMeshes","mNumMeshes"); - } - else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) { - ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there"); - } - else if (pScene->mMeshes) { - ReportError("aiScene::mMeshes is non-null although there are no meshes"); - } - - // validate all animations - if (pScene->mNumAnimations) { - DoValidation(pScene->mAnimations,pScene->mNumAnimations, - "mAnimations","mNumAnimations"); - } - else if (pScene->mAnimations) { - ReportError("aiScene::mAnimations is non-null although there are no animations"); - } - - // validate all cameras - if (pScene->mNumCameras) { - DoValidationWithNameCheck(pScene->mCameras,pScene->mNumCameras, - "mCameras","mNumCameras"); - } - else if (pScene->mCameras) { - ReportError("aiScene::mCameras is non-null although there are no cameras"); - } - - // validate all lights - if (pScene->mNumLights) { - DoValidationWithNameCheck(pScene->mLights,pScene->mNumLights, - "mLights","mNumLights"); - } - else if (pScene->mLights) { - ReportError("aiScene::mLights is non-null although there are no lights"); - } - - // validate all textures - if (pScene->mNumTextures) { - DoValidation(pScene->mTextures,pScene->mNumTextures, - "mTextures","mNumTextures"); - } - else if (pScene->mTextures) { - ReportError("aiScene::mTextures is non-null although there are no textures"); - } - - // validate all materials - if (pScene->mNumMaterials) { - DoValidation(pScene->mMaterials,pScene->mNumMaterials,"mMaterials","mNumMaterials"); - } -#if 0 - // NOTE: ScenePreprocessor generates a default material if none is there - else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) { - ReportError("aiScene::mNumMaterials is 0. At least one material must be there"); - } -#endif - else if (pScene->mMaterials) { - ReportError("aiScene::mMaterials is non-null although there are no materials"); - } - -// if (!has)ReportError("The aiScene data structure is empty"); - ASSIMP_LOG_DEBUG("ValidateDataStructureProcess end"); -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiLight* pLight) -{ - if (pLight->mType == aiLightSource_UNDEFINED) - ReportWarning("aiLight::mType is aiLightSource_UNDEFINED"); - - if (!pLight->mAttenuationConstant && - !pLight->mAttenuationLinear && - !pLight->mAttenuationQuadratic) { - ReportWarning("aiLight::mAttenuationXXX - all are zero"); - } - - if (pLight->mAngleInnerCone > pLight->mAngleOuterCone) - ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone"); - - if (pLight->mColorDiffuse.IsBlack() && pLight->mColorAmbient.IsBlack() - && pLight->mColorSpecular.IsBlack()) - { - ReportWarning("aiLight::mColorXXX - all are black and won't have any influence"); - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiCamera* pCamera) -{ - if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear) - ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear"); - - // FIX: there are many 3ds files with invalid FOVs. No reason to - // reject them at all ... a warning is appropriate. - if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI) - ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV); -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiMesh* pMesh) -{ - // validate the material index of the mesh - if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials) - { - ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)", - pMesh->mMaterialIndex,mScene->mNumMaterials-1); - } - - Validate(&pMesh->mName); - - for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) - { - aiFace& face = pMesh->mFaces[i]; - - if (pMesh->mPrimitiveTypes) - { - switch (face.mNumIndices) - { - case 0: - ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i); - break; - case 1: - if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) - { - ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes " - "does not report the POINT flag",i); - } - break; - case 2: - if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE)) - { - ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes " - "does not report the LINE flag",i); - } - break; - case 3: - if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)) - { - ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes " - "does not report the TRIANGLE flag",i); - } - break; - default: - if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) - { - this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes " - "does not report the POLYGON flag",i); - } - break; - }; - } - - if (!face.mIndices) - ReportError("aiMesh::mFaces[%i].mIndices is NULL",i); - } - - // positions must always be there ... - if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) { - ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str()); - } - - if (pMesh->mNumVertices > AI_MAX_VERTICES) { - ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES); - } - if (pMesh->mNumFaces > AI_MAX_FACES) { - ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES); - } - - // if tangents are there there must also be bitangent vectors ... - if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL)) { - ReportError("If there are tangents, bitangent vectors must be present as well"); - } - - // faces, too - if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) { - ReportError("Mesh %s contains no faces", pMesh->mName.C_Str()); - } - - // now check whether the face indexing layout is correct: - // unique vertices, pseudo-indexed. - std::vector<bool> abRefList; - abRefList.resize(pMesh->mNumVertices,false); - for (unsigned int i = 0; i < pMesh->mNumFaces;++i) - { - aiFace& face = pMesh->mFaces[i]; - if (face.mNumIndices > AI_MAX_FACE_INDICES) { - ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES); - } - - for (unsigned int a = 0; a < face.mNumIndices;++a) - { - if (face.mIndices[a] >= pMesh->mNumVertices) { - ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a); - } - // the MSB flag is temporarily used by the extra verbose - // mode to tell us that the JoinVerticesProcess might have - // been executed already. - /*if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) && - abRefList[face.mIndices[a]]) - { - ReportError("aiMesh::mVertices[%i] is referenced twice - second " - "time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a); - }*/ - abRefList[face.mIndices[a]] = true; - } - } - - // check whether there are vertices that aren't referenced by a face - bool b = false; - for (unsigned int i = 0; i < pMesh->mNumVertices;++i) { - if (!abRefList[i])b = true; - } - abRefList.clear(); - if (b) { - ReportWarning("There are unreferenced vertices"); - } - - // texture channel 2 may not be set if channel 1 is zero ... - { - unsigned int i = 0; - for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) - { - if (!pMesh->HasTextureCoords(i))break; - } - for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) - if (pMesh->HasTextureCoords(i)) - { - ReportError("Texture coordinate channel %i exists " - "although the previous channel was NULL.",i); - } - } - // the same for the vertex colors - { - unsigned int i = 0; - for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i) - { - if (!pMesh->HasVertexColors(i))break; - } - for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i) - if (pMesh->HasVertexColors(i)) - { - ReportError("Vertex color channel %i is exists " - "although the previous channel was NULL.",i); - } - } - - - // now validate all bones - if (pMesh->mNumBones) - { - if (!pMesh->mBones) - { - ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)", - pMesh->mNumBones); - } - std::unique_ptr<float[]> afSum(nullptr); - if (pMesh->mNumVertices) - { - afSum.reset(new float[pMesh->mNumVertices]); - for (unsigned int i = 0; i < pMesh->mNumVertices;++i) - afSum[i] = 0.0f; - } - - // check whether there are duplicate bone names - for (unsigned int i = 0; i < pMesh->mNumBones;++i) - { - const aiBone* bone = pMesh->mBones[i]; - if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) { - ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS); - } - - if (!pMesh->mBones[i]) - { - ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)", - i,pMesh->mNumBones); - } - Validate(pMesh,pMesh->mBones[i],afSum.get()); - - for (unsigned int a = i+1; a < pMesh->mNumBones;++a) - { - if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName) - { - const char *name = "unknown"; - if (nullptr != pMesh->mBones[ i ]->mName.C_Str()) { - name = pMesh->mBones[ i ]->mName.C_Str(); - } - ReportError("aiMesh::mBones[%i], name = \"%s\" has the same name as " - "aiMesh::mBones[%i]", i, name, a ); - } - } - } - // check whether all bone weights for a vertex sum to 1.0 ... - for (unsigned int i = 0; i < pMesh->mNumVertices;++i) - { - if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05)) { - ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]); - } - } - } - else if (pMesh->mBones) - { - ReportError("aiMesh::mBones is non-null although there are no bones"); - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiMesh* pMesh, const aiBone* pBone,float* afSum) { - this->Validate(&pBone->mName); - - if (!pBone->mNumWeights) { - //ReportError("aiBone::mNumWeights is zero"); - } - - // check whether all vertices affected by this bone are valid - for (unsigned int i = 0; i < pBone->mNumWeights;++i) - { - if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices) { - ReportError("aiBone::mWeights[%i].mVertexId is out of range",i); - } - else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f) { - ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i); - } - afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight; - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiAnimation* pAnimation) -{ - Validate(&pAnimation->mName); - - // validate all animations - if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels) - { - if (!pAnimation->mChannels && pAnimation->mNumChannels) { - ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)", - pAnimation->mNumChannels); - } - if (!pAnimation->mMorphMeshChannels && pAnimation->mNumMorphMeshChannels) { - ReportError("aiAnimation::mMorphMeshChannels is NULL (aiAnimation::mNumMorphMeshChannels is %i)", - pAnimation->mNumMorphMeshChannels); - } - for (unsigned int i = 0; i < pAnimation->mNumChannels;++i) - { - if (!pAnimation->mChannels[i]) - { - ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)", - i, pAnimation->mNumChannels); - } - Validate(pAnimation, pAnimation->mChannels[i]); - } - for (unsigned int i = 0; i < pAnimation->mNumMorphMeshChannels;++i) - { - if (!pAnimation->mMorphMeshChannels[i]) - { - ReportError("aiAnimation::mMorphMeshChannels[%i] is NULL (aiAnimation::mNumMorphMeshChannels is %i)", - i, pAnimation->mNumMorphMeshChannels); - } - Validate(pAnimation, pAnimation->mMorphMeshChannels[i]); - } - } - else { - ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there."); - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial, - aiTextureType type) -{ - const char* szType = TextureTypeToString(type); - - // **************************************************************************** - // Search all keys of the material ... - // textures must be specified with ascending indices - // (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...) - // **************************************************************************** - - int iNumIndices = 0; - int iIndex = -1; - for (unsigned int i = 0; i < pMaterial->mNumProperties;++i) { - aiMaterialProperty* prop = pMaterial->mProperties[ i ]; - ai_assert(nullptr != prop); - if ( !::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == static_cast<unsigned int>(type)) { - iIndex = std::max(iIndex, (int) prop->mIndex); - ++iNumIndices; - - if (aiPTI_String != prop->mType) { - ReportError("Material property %s is expected to be a string", prop->mKey.data); - } - } - } - if (iIndex +1 != iNumIndices) { - ReportError("%s #%i is set, but there are only %i %s textures", - szType,iIndex,iNumIndices,szType); - } - if (!iNumIndices)return; - std::vector<aiTextureMapping> mappings(iNumIndices); - - // Now check whether all UV indices are valid ... - bool bNoSpecified = true; - for (unsigned int i = 0; i < pMaterial->mNumProperties;++i) - { - aiMaterialProperty* prop = pMaterial->mProperties[i]; - if (prop->mSemantic != type)continue; - - if ((int)prop->mIndex >= iNumIndices) - { - ReportError("Found texture property with index %i, although there " - "are only %i textures of type %s", - prop->mIndex, iNumIndices, szType); - } - - if (!::strcmp(prop->mKey.data,"$tex.mapping")) { - if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping)) - { - ReportError("Material property %s%i is expected to be an integer (size is %i)", - prop->mKey.data,prop->mIndex,prop->mDataLength); - } - mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData); - } - else if (!::strcmp(prop->mKey.data,"$tex.uvtrafo")) { - if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform)) - { - ReportError("Material property %s%i is expected to be 5 floats large (size is %i)", - prop->mKey.data,prop->mIndex, prop->mDataLength); - } - mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData); - } - else if (!::strcmp(prop->mKey.data,"$tex.uvwsrc")) { - if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength) - { - ReportError("Material property %s%i is expected to be an integer (size is %i)", - prop->mKey.data,prop->mIndex,prop->mDataLength); - } - bNoSpecified = false; - - // Ignore UV indices for texture channels that are not there ... - - // Get the value - iIndex = *((unsigned int*)prop->mData); - - // Check whether there is a mesh using this material - // which has not enough UV channels ... - for (unsigned int a = 0; a < mScene->mNumMeshes;++a) - { - aiMesh* mesh = this->mScene->mMeshes[a]; - if(mesh->mMaterialIndex == (unsigned int)i) - { - int iChannels = 0; - while (mesh->HasTextureCoords(iChannels))++iChannels; - if (iIndex >= iChannels) - { - ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels", - iIndex,prop->mKey.data,a,iChannels); - } - } - } - } - } - if (bNoSpecified) - { - // Assume that all textures are using the first UV channel - for (unsigned int a = 0; a < mScene->mNumMeshes;++a) - { - aiMesh* mesh = mScene->mMeshes[a]; - if(mesh->mMaterialIndex == (unsigned int)iIndex && mappings[0] == aiTextureMapping_UV) - { - if (!mesh->mTextureCoords[0]) - { - // This is a special case ... it could be that the - // original mesh format intended the use of a special - // mapping here. - ReportWarning("UV-mapped texture, but there are no UV coords"); - } - } - } - } -} -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiMaterial* pMaterial) -{ - // check whether there are material keys that are obviously not legal - for (unsigned int i = 0; i < pMaterial->mNumProperties;++i) - { - const aiMaterialProperty* prop = pMaterial->mProperties[i]; - if (!prop) { - ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)", - i,pMaterial->mNumProperties); - } - if (!prop->mDataLength || !prop->mData) { - ReportError("aiMaterial::mProperties[%i].mDataLength or " - "aiMaterial::mProperties[%i].mData is 0",i,i); - } - // check all predefined types - if (aiPTI_String == prop->mType) { - // FIX: strings are now stored in a less expensive way, but we can't use the - // validation routine for 'normal' aiStrings - if (prop->mDataLength < 5 || prop->mDataLength < 4 + (*reinterpret_cast<uint32_t*>(prop->mData)) + 1) { - ReportError("aiMaterial::mProperties[%i].mDataLength is " - "too small to contain a string (%i, needed: %i)", - i,prop->mDataLength,static_cast<int>(sizeof(aiString))); - } - if(prop->mData[prop->mDataLength-1]) { - ReportError("Missing null-terminator in string material property"); - } - // Validate((const aiString*)prop->mData); - } - else if (aiPTI_Float == prop->mType) { - if (prop->mDataLength < sizeof(float)) { - ReportError("aiMaterial::mProperties[%i].mDataLength is " - "too small to contain a float (%i, needed: %i)", - i,prop->mDataLength, static_cast<int>(sizeof(float))); - } - } - else if (aiPTI_Integer == prop->mType) { - if (prop->mDataLength < sizeof(int)) { - ReportError("aiMaterial::mProperties[%i].mDataLength is " - "too small to contain an integer (%i, needed: %i)", - i,prop->mDataLength, static_cast<int>(sizeof(int))); - } - } - // TODO: check whether there is a key with an unknown name ... - } - - // make some more specific tests - ai_real fTemp; - int iShading; - if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading)) { - switch ((aiShadingMode)iShading) - { - case aiShadingMode_Blinn: - case aiShadingMode_CookTorrance: - case aiShadingMode_Phong: - - if (AI_SUCCESS != aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS,&fTemp)) { - ReportWarning("A specular shading model is specified but there is no " - "AI_MATKEY_SHININESS key"); - } - if (AI_SUCCESS == aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS_STRENGTH,&fTemp) && !fTemp) { - ReportWarning("A specular shading model is specified but the value of the " - "AI_MATKEY_SHININESS_STRENGTH key is 0.0"); - } - break; - default: - break; - } - } - - if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) { - ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)"); - } - - // Check whether there are invalid texture keys - // TODO: that's a relict of the past, where texture type and index were baked - // into the material string ... we could do that in one single pass. - SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE); - SearchForInvalidTextures(pMaterial,aiTextureType_SPECULAR); - SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT); - SearchForInvalidTextures(pMaterial,aiTextureType_EMISSIVE); - SearchForInvalidTextures(pMaterial,aiTextureType_OPACITY); - SearchForInvalidTextures(pMaterial,aiTextureType_SHININESS); - SearchForInvalidTextures(pMaterial,aiTextureType_HEIGHT); - SearchForInvalidTextures(pMaterial,aiTextureType_NORMALS); - SearchForInvalidTextures(pMaterial,aiTextureType_DISPLACEMENT); - SearchForInvalidTextures(pMaterial,aiTextureType_LIGHTMAP); - SearchForInvalidTextures(pMaterial,aiTextureType_REFLECTION); -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiTexture* pTexture) -{ - // the data section may NEVER be NULL - if (!pTexture->pcData) { - ReportError("aiTexture::pcData is NULL"); - } - if (pTexture->mHeight) - { - if (!pTexture->mWidth){ - ReportError("aiTexture::mWidth is zero (aiTexture::mHeight is %i, uncompressed texture)", - pTexture->mHeight); - } - } - else - { - if (!pTexture->mWidth) { - ReportError("aiTexture::mWidth is zero (compressed texture)"); - } - if ('\0' != pTexture->achFormatHint[3]) { - ReportWarning("aiTexture::achFormatHint must be zero-terminated"); - } - else if ('.' == pTexture->achFormatHint[0]) { - ReportWarning("aiTexture::achFormatHint should contain a file extension " - "without a leading dot (format hint: %s).",pTexture->achFormatHint); - } - } - - const char* sz = pTexture->achFormatHint; - if ((sz[0] >= 'A' && sz[0] <= 'Z') || - (sz[1] >= 'A' && sz[1] <= 'Z') || - (sz[2] >= 'A' && sz[2] <= 'Z') || - (sz[3] >= 'A' && sz[3] <= 'Z')) { - ReportError("aiTexture::achFormatHint contains non-lowercase letters"); - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiAnimation* pAnimation, - const aiNodeAnim* pNodeAnim) -{ - Validate(&pNodeAnim->mNodeName); - - if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys) { - ReportError("Empty node animation channel"); - } - // otherwise check whether one of the keys exceeds the total duration of the animation - if (pNodeAnim->mNumPositionKeys) - { - if (!pNodeAnim->mPositionKeys) - { - ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)", - pNodeAnim->mNumPositionKeys); - } - double dLast = -10e10; - for (unsigned int i = 0; i < pNodeAnim->mNumPositionKeys;++i) - { - // ScenePreprocessor will compute the duration if still the default value - // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration, - // seems to be due the compilers register usage/width. - if (pAnimation->mDuration > 0. && pNodeAnim->mPositionKeys[i].mTime > pAnimation->mDuration+0.001) - { - ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger " - "than aiAnimation::mDuration (which is %.5f)",i, - (float)pNodeAnim->mPositionKeys[i].mTime, - (float)pAnimation->mDuration); - } - if (i && pNodeAnim->mPositionKeys[i].mTime <= dLast) - { - ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller " - "than aiAnimation::mPositionKeys[%i] (which is %.5f)",i, - (float)pNodeAnim->mPositionKeys[i].mTime, - i-1, (float)dLast); - } - dLast = pNodeAnim->mPositionKeys[i].mTime; - } - } - // rotation keys - if (pNodeAnim->mNumRotationKeys) - { - if (!pNodeAnim->mRotationKeys) - { - ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)", - pNodeAnim->mNumRotationKeys); - } - double dLast = -10e10; - for (unsigned int i = 0; i < pNodeAnim->mNumRotationKeys;++i) - { - if (pAnimation->mDuration > 0. && pNodeAnim->mRotationKeys[i].mTime > pAnimation->mDuration+0.001) - { - ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger " - "than aiAnimation::mDuration (which is %.5f)",i, - (float)pNodeAnim->mRotationKeys[i].mTime, - (float)pAnimation->mDuration); - } - if (i && pNodeAnim->mRotationKeys[i].mTime <= dLast) - { - ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller " - "than aiAnimation::mRotationKeys[%i] (which is %.5f)",i, - (float)pNodeAnim->mRotationKeys[i].mTime, - i-1, (float)dLast); - } - dLast = pNodeAnim->mRotationKeys[i].mTime; - } - } - // scaling keys - if (pNodeAnim->mNumScalingKeys) - { - if (!pNodeAnim->mScalingKeys) { - ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)", - pNodeAnim->mNumScalingKeys); - } - double dLast = -10e10; - for (unsigned int i = 0; i < pNodeAnim->mNumScalingKeys;++i) - { - if (pAnimation->mDuration > 0. && pNodeAnim->mScalingKeys[i].mTime > pAnimation->mDuration+0.001) - { - ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger " - "than aiAnimation::mDuration (which is %.5f)",i, - (float)pNodeAnim->mScalingKeys[i].mTime, - (float)pAnimation->mDuration); - } - if (i && pNodeAnim->mScalingKeys[i].mTime <= dLast) - { - ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller " - "than aiAnimation::mScalingKeys[%i] (which is %.5f)",i, - (float)pNodeAnim->mScalingKeys[i].mTime, - i-1, (float)dLast); - } - dLast = pNodeAnim->mScalingKeys[i].mTime; - } - } - - if (!pNodeAnim->mNumScalingKeys && !pNodeAnim->mNumRotationKeys && - !pNodeAnim->mNumPositionKeys) - { - ReportError("A node animation channel must have at least one subtrack"); - } -} - -void ValidateDSProcess::Validate( const aiAnimation* pAnimation, - const aiMeshMorphAnim* pMeshMorphAnim) -{ - Validate(&pMeshMorphAnim->mName); - - if (!pMeshMorphAnim->mNumKeys) { - ReportError("Empty mesh morph animation channel"); - } - - // otherwise check whether one of the keys exceeds the total duration of the animation - if (pMeshMorphAnim->mNumKeys) - { - if (!pMeshMorphAnim->mKeys) - { - ReportError("aiMeshMorphAnim::mKeys is NULL (aiMeshMorphAnim::mNumKeys is %i)", - pMeshMorphAnim->mNumKeys); - } - double dLast = -10e10; - for (unsigned int i = 0; i < pMeshMorphAnim->mNumKeys;++i) - { - // ScenePreprocessor will compute the duration if still the default value - // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration, - // seems to be due the compilers register usage/width. - if (pAnimation->mDuration > 0. && pMeshMorphAnim->mKeys[i].mTime > pAnimation->mDuration+0.001) - { - ReportError("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is larger " - "than aiAnimation::mDuration (which is %.5f)",i, - (float)pMeshMorphAnim->mKeys[i].mTime, - (float)pAnimation->mDuration); - } - if (i && pMeshMorphAnim->mKeys[i].mTime <= dLast) - { - ReportWarning("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is smaller " - "than aiMeshMorphAnim::mKeys[%i] (which is %.5f)",i, - (float)pMeshMorphAnim->mKeys[i].mTime, - i-1, (float)dLast); - } - dLast = pMeshMorphAnim->mKeys[i].mTime; - } - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiNode* pNode) -{ - if (!pNode) { - ReportError("A node of the scenegraph is NULL"); - } - // Validate node name string first so that it's safe to use in below expressions - this->Validate(&pNode->mName); - const char* nodeName = (&pNode->mName)->C_Str(); - if (pNode != mScene->mRootNode && !pNode->mParent){ - ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ", nodeName); - } - - // validate all meshes - if (pNode->mNumMeshes) - { - if (!pNode->mMeshes) - { - ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)", - nodeName, pNode->mNumMeshes); - } - std::vector<bool> abHadMesh; - abHadMesh.resize(mScene->mNumMeshes,false); - for (unsigned int i = 0; i < pNode->mNumMeshes;++i) - { - if (pNode->mMeshes[i] >= mScene->mNumMeshes) - { - ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)", - pNode->mMeshes[i], nodeName, mScene->mNumMeshes-1); - } - if (abHadMesh[pNode->mMeshes[i]]) - { - ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)", - i, nodeName, pNode->mMeshes[i]); - } - abHadMesh[pNode->mMeshes[i]] = true; - } - } - if (pNode->mNumChildren) - { - if (!pNode->mChildren) { - ReportError("aiNode::mChildren is NULL for node %s (aiNode::mNumChildren is %i)", - nodeName, pNode->mNumChildren); - } - for (unsigned int i = 0; i < pNode->mNumChildren;++i) { - Validate(pNode->mChildren[i]); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void ValidateDSProcess::Validate( const aiString* pString) -{ - if (pString->length > MAXLEN) - { - ReportError("aiString::length is too large (%u, maximum is %lu)", - pString->length,MAXLEN); - } - const char* sz = pString->data; - while (true) - { - if ('\0' == *sz) - { - if (pString->length != (unsigned int)(sz-pString->data)) { - ReportError("aiString::data is invalid: the terminal zero is at a wrong offset"); - } - break; - } - else if (sz >= &pString->data[MAXLEN]) { - ReportError("aiString::data is invalid. There is no terminal character"); - } - ++sz; - } -} diff --git a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h deleted file mode 100644 index 7b309c9251..0000000000 --- a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h +++ /dev/null @@ -1,197 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a (dummy) post processing step to validate the loader's - * output data structure (for debugging) - */ -#ifndef AI_VALIDATEPROCESS_H_INC -#define AI_VALIDATEPROCESS_H_INC - -#include <assimp/types.h> -#include <assimp/material.h> - -#include "Common/BaseProcess.h" - -struct aiBone; -struct aiMesh; -struct aiAnimation; -struct aiNodeAnim; -struct aiMeshMorphAnim; -struct aiTexture; -struct aiMaterial; -struct aiNode; -struct aiString; -struct aiCamera; -struct aiLight; - -namespace Assimp { - -// -------------------------------------------------------------------------------------- -/** Validates the whole ASSIMP scene data structure for correctness. - * ImportErrorException is thrown of the scene is corrupt.*/ -// -------------------------------------------------------------------------------------- -class ValidateDSProcess : public BaseProcess -{ -public: - - ValidateDSProcess(); - ~ValidateDSProcess(); - -public: - // ------------------------------------------------------------------- - bool IsActive( unsigned int pFlags) const; - - // ------------------------------------------------------------------- - void Execute( aiScene* pScene); - -protected: - - // ------------------------------------------------------------------- - /** Report a validation error. This will throw an exception, - * control won't return. - * @param msg Format string for sprintf().*/ - AI_WONT_RETURN void ReportError(const char* msg,...) AI_WONT_RETURN_SUFFIX; - - - // ------------------------------------------------------------------- - /** Report a validation warning. This won't throw an exception, - * control will return to the caller. - * @param msg Format string for sprintf().*/ - void ReportWarning(const char* msg,...); - - - // ------------------------------------------------------------------- - /** Validates a mesh - * @param pMesh Input mesh*/ - void Validate( const aiMesh* pMesh); - - // ------------------------------------------------------------------- - /** Validates a bone - * @param pMesh Input mesh - * @param pBone Input bone*/ - void Validate( const aiMesh* pMesh,const aiBone* pBone,float* afSum); - - // ------------------------------------------------------------------- - /** Validates an animation - * @param pAnimation Input animation*/ - void Validate( const aiAnimation* pAnimation); - - // ------------------------------------------------------------------- - /** Validates a material - * @param pMaterial Input material*/ - void Validate( const aiMaterial* pMaterial); - - // ------------------------------------------------------------------- - /** Search the material data structure for invalid or corrupt - * texture keys. - * @param pMaterial Input material - * @param type Type of the texture*/ - void SearchForInvalidTextures(const aiMaterial* pMaterial, - aiTextureType type); - - // ------------------------------------------------------------------- - /** Validates a texture - * @param pTexture Input texture*/ - void Validate( const aiTexture* pTexture); - - // ------------------------------------------------------------------- - /** Validates a light source - * @param pLight Input light - */ - void Validate( const aiLight* pLight); - - // ------------------------------------------------------------------- - /** Validates a camera - * @param pCamera Input camera*/ - void Validate( const aiCamera* pCamera); - - // ------------------------------------------------------------------- - /** Validates a bone animation channel - * @param pAnimation Animation channel. - * @param pBoneAnim Input bone animation */ - void Validate( const aiAnimation* pAnimation, - const aiNodeAnim* pBoneAnim); - - /** Validates a mesh morph animation channel. - * @param pAnimation Input animation. - * @param pMeshMorphAnim Mesh morph animation channel. - * */ - void Validate( const aiAnimation* pAnimation, - const aiMeshMorphAnim* pMeshMorphAnim); - - // ------------------------------------------------------------------- - /** Validates a node and all of its subnodes - * @param Node Input node*/ - void Validate( const aiNode* pNode); - - // ------------------------------------------------------------------- - /** Validates a string - * @param pString Input string*/ - void Validate( const aiString* pString); - -private: - - // template to validate one of the aiScene::mXXX arrays - template <typename T> - inline void DoValidation(T** array, unsigned int size, - const char* firstName, const char* secondName); - - // extended version: checks whether T::mName occurs twice - template <typename T> - inline void DoValidationEx(T** array, unsigned int size, - const char* firstName, const char* secondName); - - // extension to the first template which does also search - // the nodegraph for an item with the same name - template <typename T> - inline void DoValidationWithNameCheck(T** array, unsigned int size, - const char* firstName, const char* secondName); - - aiScene* mScene; -}; - - - - -} // end of namespace Assimp - -#endif // AI_VALIDATEPROCESS_H_INC diff --git a/thirdparty/assimp/contrib/utf8cpp/source/utf8.h b/thirdparty/assimp/contrib/utf8cpp/source/utf8.h deleted file mode 100644 index 82b13f59f9..0000000000 --- a/thirdparty/assimp/contrib/utf8cpp/source/utf8.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - - -#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include "utf8/checked.h" -#include "utf8/unchecked.h" - -#endif // header guard diff --git a/thirdparty/assimp/contrib/utf8cpp/source/utf8/checked.h b/thirdparty/assimp/contrib/utf8cpp/source/utf8/checked.h deleted file mode 100644 index 1331155138..0000000000 --- a/thirdparty/assimp/contrib/utf8cpp/source/utf8/checked.h +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - - -#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include "core.h" -#include <stdexcept> - -namespace utf8 -{ - // Base for the exceptions that may be thrown from the library - class exception : public ::std::exception { - }; - - // Exceptions that may be thrown from the library functions. - class invalid_code_point : public exception { - uint32_t cp; - public: - invalid_code_point(uint32_t cp) : cp(cp) {} - virtual const char* what() const throw() { return "Invalid code point"; } - uint32_t code_point() const {return cp;} - }; - - class invalid_utf8 : public exception { - uint8_t u8; - public: - invalid_utf8 (uint8_t u) : u8(u) {} - virtual const char* what() const throw() { return "Invalid UTF-8"; } - uint8_t utf8_octet() const {return u8;} - }; - - class invalid_utf16 : public exception { - uint16_t u16; - public: - invalid_utf16 (uint16_t u) : u16(u) {} - virtual const char* what() const throw() { return "Invalid UTF-16"; } - uint16_t utf16_word() const {return u16;} - }; - - class not_enough_room : public exception { - public: - virtual const char* what() const throw() { return "Not enough space"; } - }; - - /// The library API - functions intended to be called by the users - - template <typename octet_iterator> - octet_iterator append(uint32_t cp, octet_iterator result) - { - if (!utf8::internal::is_code_point_valid(cp)) - throw invalid_code_point(cp); - - if (cp < 0x80) // one octet - *(result++) = static_cast<uint8_t>(cp); - else if (cp < 0x800) { // two octets - *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0); - *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80); - } - else if (cp < 0x10000) { // three octets - *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0); - *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80); - } - else { // four octets - *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0); - *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80); - *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80); - } - return result; - } - - template <typename octet_iterator, typename output_iterator> - output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) - { - while (start != end) { - octet_iterator sequence_start = start; - internal::utf_error err_code = utf8::internal::validate_next(start, end); - switch (err_code) { - case internal::UTF8_OK : - for (octet_iterator it = sequence_start; it != start; ++it) - *out++ = *it; - break; - case internal::NOT_ENOUGH_ROOM: - throw not_enough_room(); - case internal::INVALID_LEAD: - out = utf8::append (replacement, out); - ++start; - break; - case internal::INCOMPLETE_SEQUENCE: - case internal::OVERLONG_SEQUENCE: - case internal::INVALID_CODE_POINT: - out = utf8::append (replacement, out); - ++start; - // just one replacement mark for the sequence - while (start != end && utf8::internal::is_trail(*start)) - ++start; - break; - } - } - return out; - } - - template <typename octet_iterator, typename output_iterator> - inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) - { - static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); - return utf8::replace_invalid(start, end, out, replacement_marker); - } - - template <typename octet_iterator> - uint32_t next(octet_iterator& it, octet_iterator end) - { - uint32_t cp = 0; - internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); - switch (err_code) { - case internal::UTF8_OK : - break; - case internal::NOT_ENOUGH_ROOM : - throw not_enough_room(); - case internal::INVALID_LEAD : - case internal::INCOMPLETE_SEQUENCE : - case internal::OVERLONG_SEQUENCE : - throw invalid_utf8(*it); - case internal::INVALID_CODE_POINT : - throw invalid_code_point(cp); - } - return cp; - } - - template <typename octet_iterator> - uint32_t peek_next(octet_iterator it, octet_iterator end) - { - return utf8::next(it, end); - } - - template <typename octet_iterator> - uint32_t prior(octet_iterator& it, octet_iterator start) - { - // can't do much if it == start - if (it == start) - throw not_enough_room(); - - octet_iterator end = it; - // Go back until we hit either a lead octet or start - while (utf8::internal::is_trail(*(--it))) - if (it == start) - throw invalid_utf8(*it); // error - no lead byte in the sequence - return utf8::peek_next(it, end); - } - - /// Deprecated in versions that include "prior" - template <typename octet_iterator> - uint32_t previous(octet_iterator& it, octet_iterator pass_start) - { - octet_iterator end = it; - while (utf8::internal::is_trail(*(--it))) - if (it == pass_start) - throw invalid_utf8(*it); // error - no lead byte in the sequence - octet_iterator temp = it; - return utf8::next(temp, end); - } - - template <typename octet_iterator, typename distance_type> - void advance (octet_iterator& it, distance_type n, octet_iterator end) - { - for (distance_type i = 0; i < n; ++i) - utf8::next(it, end); - } - - template <typename octet_iterator> - typename std::iterator_traits<octet_iterator>::difference_type - distance (octet_iterator first, octet_iterator last) - { - typename std::iterator_traits<octet_iterator>::difference_type dist; - for (dist = 0; first < last; ++dist) - utf8::next(first, last); - return dist; - } - - template <typename u16bit_iterator, typename octet_iterator> - octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) - { - while (start != end) { - uint32_t cp = utf8::internal::mask16(*start++); - // Take care of surrogate pairs first - if (utf8::internal::is_lead_surrogate(cp)) { - if (start != end) { - uint32_t trail_surrogate = utf8::internal::mask16(*start++); - if (utf8::internal::is_trail_surrogate(trail_surrogate)) - cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; - else - throw invalid_utf16(static_cast<uint16_t>(trail_surrogate)); - } - else - throw invalid_utf16(static_cast<uint16_t>(cp)); - - } - // Lone trail surrogate - else if (utf8::internal::is_trail_surrogate(cp)) - throw invalid_utf16(static_cast<uint16_t>(cp)); - - result = utf8::append(cp, result); - } - return result; - } - - template <typename u16bit_iterator, typename octet_iterator> - u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) - { - while (start != end) { - uint32_t cp = utf8::next(start, end); - if (cp > 0xffff) { //make a surrogate pair - *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET); - *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); - } - else - *result++ = static_cast<uint16_t>(cp); - } - return result; - } - - template <typename octet_iterator, typename u32bit_iterator> - octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) - { - while (start != end) - result = utf8::append(*(start++), result); - - return result; - } - - template <typename octet_iterator, typename u32bit_iterator> - u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) - { - while (start != end) - (*result++) = utf8::next(start, end); - - return result; - } - - // The iterator class - template <typename octet_iterator> - class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> { - octet_iterator it; - octet_iterator range_start; - octet_iterator range_end; - public: - iterator () {} - explicit iterator (const octet_iterator& octet_it, - const octet_iterator& range_start, - const octet_iterator& range_end) : - it(octet_it), range_start(range_start), range_end(range_end) - { - if (it < range_start || it > range_end) - throw std::out_of_range("Invalid utf-8 iterator position"); - } - // the default "big three" are OK - octet_iterator base () const { return it; } - uint32_t operator * () const - { - octet_iterator temp = it; - return utf8::next(temp, range_end); - } - bool operator == (const iterator& rhs) const - { - if (range_start != rhs.range_start || range_end != rhs.range_end) - throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); - return (it == rhs.it); - } - bool operator != (const iterator& rhs) const - { - return !(operator == (rhs)); - } - iterator& operator ++ () - { - utf8::next(it, range_end); - return *this; - } - iterator operator ++ (int) - { - iterator temp = *this; - utf8::next(it, range_end); - return temp; - } - iterator& operator -- () - { - utf8::prior(it, range_start); - return *this; - } - iterator operator -- (int) - { - iterator temp = *this; - utf8::prior(it, range_start); - return temp; - } - }; // class iterator - -} // namespace utf8 - -#endif //header guard - - diff --git a/thirdparty/assimp/contrib/utf8cpp/source/utf8/core.h b/thirdparty/assimp/contrib/utf8cpp/source/utf8/core.h deleted file mode 100644 index 693d388c07..0000000000 --- a/thirdparty/assimp/contrib/utf8cpp/source/utf8/core.h +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - - -#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include <iterator> - -namespace utf8 -{ - // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers - // You may need to change them to match your system. - // These typedefs have the same names as ones from cstdint, or boost/cstdint - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - -// Helper code - not intended to be directly called by the library users. May be changed at any time -namespace internal -{ - // Unicode constants - // Leading (high) surrogates: 0xd800 - 0xdbff - // Trailing (low) surrogates: 0xdc00 - 0xdfff - const uint16_t LEAD_SURROGATE_MIN = 0xd800u; - const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; - const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; - const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; - const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); - const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; - - // Maximum valid value for a Unicode code point - const uint32_t CODE_POINT_MAX = 0x0010ffffu; - - template<typename octet_type> - inline uint8_t mask8(octet_type oc) - { - return static_cast<uint8_t>(0xff & oc); - } - template<typename u16_type> - inline uint16_t mask16(u16_type oc) - { - return static_cast<uint16_t>(0xffff & oc); - } - template<typename octet_type> - inline bool is_trail(octet_type oc) - { - return ((utf8::internal::mask8(oc) >> 6) == 0x2); - } - - template <typename u16> - inline bool is_lead_surrogate(u16 cp) - { - return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); - } - - template <typename u16> - inline bool is_trail_surrogate(u16 cp) - { - return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); - } - - template <typename u16> - inline bool is_surrogate(u16 cp) - { - return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); - } - - template <typename u32> - inline bool is_code_point_valid(u32 cp) - { - return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); - } - - template <typename octet_iterator> - inline typename std::iterator_traits<octet_iterator>::difference_type - sequence_length(octet_iterator lead_it) - { - uint8_t lead = utf8::internal::mask8(*lead_it); - if (lead < 0x80) - return 1; - else if ((lead >> 5) == 0x6) - return 2; - else if ((lead >> 4) == 0xe) - return 3; - else if ((lead >> 3) == 0x1e) - return 4; - else - return 0; - } - - template <typename octet_difference_type> - inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) - { - if (cp < 0x80) { - if (length != 1) - return true; - } - else if (cp < 0x800) { - if (length != 2) - return true; - } - else if (cp < 0x10000) { - if (length != 3) - return true; - } - - return false; - } - - enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; - - /// Helper for get_sequence_x - template <typename octet_iterator> - utf_error increase_safely(octet_iterator& it, octet_iterator end) - { - if (++it == end) - return NOT_ENOUGH_ROOM; - - if (!utf8::internal::is_trail(*it)) - return INCOMPLETE_SEQUENCE; - - return UTF8_OK; - } - - #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} - - /// get_sequence_x functions decode utf-8 sequences of the length x - template <typename octet_iterator> - utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - return UTF8_OK; - } - - template <typename octet_iterator> - utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); - - return UTF8_OK; - } - - template <typename octet_iterator> - utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point += (*it) & 0x3f; - - return UTF8_OK; - } - - template <typename octet_iterator> - utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point += (*it) & 0x3f; - - return UTF8_OK; - } - - #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR - - template <typename octet_iterator> - utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - // Save the original value of it so we can go back in case of failure - // Of course, it does not make much sense with i.e. stream iterators - octet_iterator original_it = it; - - uint32_t cp = 0; - // Determine the sequence length based on the lead octet - typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type; - const octet_difference_type length = utf8::internal::sequence_length(it); - - // Get trail octets and calculate the code point - utf_error err = UTF8_OK; - switch (length) { - case 0: - return INVALID_LEAD; - case 1: - err = utf8::internal::get_sequence_1(it, end, cp); - break; - case 2: - err = utf8::internal::get_sequence_2(it, end, cp); - break; - case 3: - err = utf8::internal::get_sequence_3(it, end, cp); - break; - case 4: - err = utf8::internal::get_sequence_4(it, end, cp); - break; - } - - if (err == UTF8_OK) { - // Decoding succeeded. Now, security checks... - if (utf8::internal::is_code_point_valid(cp)) { - if (!utf8::internal::is_overlong_sequence(cp, length)){ - // Passed! Return here. - code_point = cp; - ++it; - return UTF8_OK; - } - else - err = OVERLONG_SEQUENCE; - } - else - err = INVALID_CODE_POINT; - } - - // Failure branch - restore the original value of the iterator - it = original_it; - return err; - } - - template <typename octet_iterator> - inline utf_error validate_next(octet_iterator& it, octet_iterator end) { - uint32_t ignored; - return utf8::internal::validate_next(it, end, ignored); - } - -} // namespace internal - - /// The library API - functions intended to be called by the users - - // Byte order mark - const uint8_t bom[] = {0xef, 0xbb, 0xbf}; - - template <typename octet_iterator> - octet_iterator find_invalid(octet_iterator start, octet_iterator end) - { - octet_iterator result = start; - while (result != end) { - utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); - if (err_code != internal::UTF8_OK) - return result; - } - return result; - } - - template <typename octet_iterator> - inline bool is_valid(octet_iterator start, octet_iterator end) - { - return (utf8::find_invalid(start, end) == end); - } - - template <typename octet_iterator> - inline bool starts_with_bom (octet_iterator it, octet_iterator end) - { - return ( - ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && - ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && - ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) - ); - } - - //Deprecated in release 2.3 - template <typename octet_iterator> - inline bool is_bom (octet_iterator it) - { - return ( - (utf8::internal::mask8(*it++)) == bom[0] && - (utf8::internal::mask8(*it++)) == bom[1] && - (utf8::internal::mask8(*it)) == bom[2] - ); - } -} // namespace utf8 - -#endif // header guard - - diff --git a/thirdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h b/thirdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h deleted file mode 100644 index cb2427166b..0000000000 --- a/thirdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - - -#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include "core.h" - -namespace utf8 -{ - namespace unchecked - { - template <typename octet_iterator> - octet_iterator append(uint32_t cp, octet_iterator result) - { - if (cp < 0x80) // one octet - *(result++) = static_cast<uint8_t>(cp); - else if (cp < 0x800) { // two octets - *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0); - *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80); - } - else if (cp < 0x10000) { // three octets - *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0); - *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80); - } - else { // four octets - *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0); - *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80); - *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80); - } - return result; - } - - template <typename octet_iterator> - uint32_t next(octet_iterator& it) - { - uint32_t cp = utf8::internal::mask8(*it); - typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it); - switch (length) { - case 1: - break; - case 2: - it++; - cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); - break; - case 3: - ++it; - cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); - ++it; - cp += (*it) & 0x3f; - break; - case 4: - ++it; - cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); - ++it; - cp += (utf8::internal::mask8(*it) << 6) & 0xfff; - ++it; - cp += (*it) & 0x3f; - break; - } - ++it; - return cp; - } - - template <typename octet_iterator> - uint32_t peek_next(octet_iterator it) - { - return utf8::unchecked::next(it); - } - - template <typename octet_iterator> - uint32_t prior(octet_iterator& it) - { - while (utf8::internal::is_trail(*(--it))) ; - octet_iterator temp = it; - return utf8::unchecked::next(temp); - } - - // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) - template <typename octet_iterator> - inline uint32_t previous(octet_iterator& it) - { - return utf8::unchecked::prior(it); - } - - template <typename octet_iterator, typename distance_type> - void advance (octet_iterator& it, distance_type n) - { - for (distance_type i = 0; i < n; ++i) - utf8::unchecked::next(it); - } - - template <typename octet_iterator> - typename std::iterator_traits<octet_iterator>::difference_type - distance (octet_iterator first, octet_iterator last) - { - typename std::iterator_traits<octet_iterator>::difference_type dist; - for (dist = 0; first < last; ++dist) - utf8::unchecked::next(first); - return dist; - } - - template <typename u16bit_iterator, typename octet_iterator> - octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) - { - while (start != end) { - uint32_t cp = utf8::internal::mask16(*start++); - // Take care of surrogate pairs first - if (utf8::internal::is_lead_surrogate(cp)) { - uint32_t trail_surrogate = utf8::internal::mask16(*start++); - cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; - } - result = utf8::unchecked::append(cp, result); - } - return result; - } - - template <typename u16bit_iterator, typename octet_iterator> - u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) - { - while (start < end) { - uint32_t cp = utf8::unchecked::next(start); - if (cp > 0xffff) { //make a surrogate pair - *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET); - *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); - } - else - *result++ = static_cast<uint16_t>(cp); - } - return result; - } - - template <typename octet_iterator, typename u32bit_iterator> - octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) - { - while (start != end) - result = utf8::unchecked::append(*(start++), result); - - return result; - } - - template <typename octet_iterator, typename u32bit_iterator> - u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) - { - while (start < end) - (*result++) = utf8::unchecked::next(start); - - return result; - } - - // The iterator class - template <typename octet_iterator> - class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> { - octet_iterator it; - public: - iterator () {} - explicit iterator (const octet_iterator& octet_it): it(octet_it) {} - // the default "big three" are OK - octet_iterator base () const { return it; } - uint32_t operator * () const - { - octet_iterator temp = it; - return utf8::unchecked::next(temp); - } - bool operator == (const iterator& rhs) const - { - return (it == rhs.it); - } - bool operator != (const iterator& rhs) const - { - return !(operator == (rhs)); - } - iterator& operator ++ () - { - ::std::advance(it, utf8::internal::sequence_length(it)); - return *this; - } - iterator operator ++ (int) - { - iterator temp = *this; - ::std::advance(it, utf8::internal::sequence_length(it)); - return temp; - } - iterator& operator -- () - { - utf8::unchecked::prior(it); - return *this; - } - iterator operator -- (int) - { - iterator temp = *this; - utf8::unchecked::prior(it); - return temp; - } - }; // class iterator - - } // namespace utf8::unchecked -} // namespace utf8 - - -#endif // header guard - diff --git a/thirdparty/assimp/include/assimp/.editorconfig b/thirdparty/assimp/include/assimp/.editorconfig deleted file mode 100644 index 9ea66423ad..0000000000 --- a/thirdparty/assimp/include/assimp/.editorconfig +++ /dev/null @@ -1,8 +0,0 @@ -# See <http://EditorConfig.org> for details - -[*.{h,hpp,inl}] -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -indent_size = 4 -indent_style = space diff --git a/thirdparty/assimp/include/assimp/BaseImporter.h b/thirdparty/assimp/include/assimp/BaseImporter.h deleted file mode 100644 index ad8a3dafd8..0000000000 --- a/thirdparty/assimp/include/assimp/BaseImporter.h +++ /dev/null @@ -1,420 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Definition of the base class for all importer worker classes. */ -#pragma once -#ifndef INCLUDED_AI_BASEIMPORTER_H -#define INCLUDED_AI_BASEIMPORTER_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include "Exceptional.h" - -#include <vector> -#include <set> -#include <map> -#include <assimp/types.h> -#include <assimp/ProgressHandler.hpp> -#include <assimp/ai_assert.h> - -struct aiScene; -struct aiImporterDesc; - -namespace Assimp { - -class Importer; -class IOSystem; -class BaseProcess; -class SharedPostProcessInfo; -class IOStream; - -// utility to do char4 to uint32 in a portable manner -#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \ - (string[1] << 16) + (string[2] << 8) + string[3])) - - -// --------------------------------------------------------------------------- -/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface - * for all importer worker classes. - * - * The interface defines two functions: CanRead() is used to check if the - * importer can handle the format of the given file. If an implementation of - * this function returns true, the importer then calls ReadFile() which - * imports the given file. ReadFile is not overridable, it just calls - * InternReadFile() and catches any ImportErrorException that might occur. - */ -class ASSIMP_API BaseImporter { - friend class Importer; - -private: - /* Pushes state into importer for the importer scale */ - virtual void UpdateImporterScale( Importer* pImp ); - -public: - - /** Constructor to be privately used by #Importer */ - BaseImporter() AI_NO_EXCEPT; - - /** Destructor, private as well */ - virtual ~BaseImporter(); - - // ------------------------------------------------------------------- - /** Returns whether the class can handle the format of the given file. - * - * The implementation should be as quick as possible. A check for - * the file extension is enough. If no suitable loader is found with - * this strategy, CanRead() is called again, the 'checkSig' parameter - * set to true this time. Now the implementation is expected to - * perform a full check of the file structure, possibly searching the - * first bytes of the file for magic identifiers or keywords. - * - * @param pFile Path and file name of the file to be examined. - * @param pIOHandler The IO handler to use for accessing any file. - * @param checkSig Set to true if this method is called a second time. - * This time, the implementation may take more time to examine the - * contents of the file to be loaded for magic bytes, keywords, etc - * to be able to load files with unknown/not existent file extensions. - * @return true if the class can read this file, false if not. - */ - virtual bool CanRead( - const std::string& pFile, - IOSystem* pIOHandler, - bool checkSig - ) const = 0; - - // ------------------------------------------------------------------- - /** Imports the given file and returns the imported data. - * If the import succeeds, ownership of the data is transferred to - * the caller. If the import fails, NULL is returned. The function - * takes care that any partially constructed data is destroyed - * beforehand. - * - * @param pImp #Importer object hosting this loader. - * @param pFile Path of the file to be imported. - * @param pIOHandler IO-Handler used to open this and possible other files. - * @return The imported data or NULL if failed. If it failed a - * human-readable error description can be retrieved by calling - * GetErrorText() - * - * @note This function is not intended to be overridden. Implement - * InternReadFile() to do the import. If an exception is thrown somewhere - * in InternReadFile(), this function will catch it and transform it into - * a suitable response to the caller. - */ - aiScene* ReadFile( - Importer* pImp, - const std::string& pFile, - IOSystem* pIOHandler - ); - - // ------------------------------------------------------------------- - /** Returns the error description of the last error that occurred. - * @return A description of the last error that occurred. An empty - * string if there was no error. - */ - const std::string& GetErrorText() const { - return m_ErrorText; - } - - // ------------------------------------------------------------------- - /** Called prior to ReadFile(). - * The function is a request to the importer to update its configuration - * basing on the Importer's configuration property list. - * @param pImp Importer instance - */ - virtual void SetupProperties( - const Importer* pImp - ); - - // ------------------------------------------------------------------- - /** Called by #Importer::GetImporterInfo to get a description of - * some loader features. Importers must provide this information. */ - virtual const aiImporterDesc* GetInfo() const = 0; - - /** - * Will be called only by scale process when scaling is requested. - */ - virtual void SetFileScale(double scale) - { - fileScale = scale; - } - - virtual double GetFileScale() const - { - return fileScale; - } - - enum ImporterUnits { - M, - MM, - CM, - INCHES, - FEET - }; - - /** - * Assimp Importer - * unit conversions available - * NOTE: Valid options are initialised in the - * constructor in the implementation file to - * work around a VS2013 compiler bug if support - * for that compiler is dropped in the future - * initialisation can be moved back here - * */ - std::map<ImporterUnits, double> importerUnits; - - virtual void SetApplicationUnits( const ImporterUnits& unit ) - { - importerScale = importerUnits[unit]; - applicationUnits = unit; - } - - virtual const ImporterUnits& GetApplicationUnits() - { - return applicationUnits; - } - - // ------------------------------------------------------------------- - /** Called by #Importer::GetExtensionList for each loaded importer. - * Take the extension list contained in the structure returned by - * #GetInfo and insert all file extensions into the given set. - * @param extension set to collect file extensions in*/ - void GetExtensionList(std::set<std::string>& extensions); - -protected: - ImporterUnits applicationUnits = ImporterUnits::M; - double importerScale = 1.0; - double fileScale = 1.0; - - - - // ------------------------------------------------------------------- - /** Imports the given file into the given scene structure. The - * function is expected to throw an ImportErrorException if there is - * an error. If it terminates normally, the data in aiScene is - * expected to be correct. Override this function to implement the - * actual importing. - * <br> - * The output scene must meet the following requirements:<br> - * <ul> - * <li>At least a root node must be there, even if its only purpose - * is to reference one mesh.</li> - * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives - * in the mesh are determined automatically in this case.</li> - * <li>the vertex data is stored in a pseudo-indexed "verbose" format. - * In fact this means that every vertex that is referenced by - * a face is unique. Or the other way round: a vertex index may - * not occur twice in a single aiMesh.</li> - * <li>aiAnimation::mDuration may be -1. Assimp determines the length - * of the animation automatically in this case as the length of - * the longest animation channel.</li> - * <li>aiMesh::mBitangents may be NULL if tangents and normals are - * given. In this case bitangents are computed as the cross product - * between normal and tangent.</li> - * <li>There needn't be a material. If none is there a default material - * is generated. However, it is recommended practice for loaders - * to generate a default material for yourself that matches the - * default material setting for the file format better than Assimp's - * generic default material. Note that default materials *should* - * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded - * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) - * texture. </li> - * </ul> - * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul> - * <li> at least one mesh must be there</li> - * <li> there may be no meshes with 0 vertices or faces</li> - * </ul> - * This won't be checked (except by the validation step): Assimp will - * crash if one of the conditions is not met! - * - * @param pFile Path of the file to be imported. - * @param pScene The scene object to hold the imported data. - * NULL is not a valid parameter. - * @param pIOHandler The IO handler to use for any file access. - * NULL is not a valid parameter. */ - virtual void InternReadFile( - const std::string& pFile, - aiScene* pScene, - IOSystem* pIOHandler - ) = 0; - -public: // static utilities - - // ------------------------------------------------------------------- - /** A utility for CanRead(). - * - * The function searches the header of a file for a specific token - * and returns true if this token is found. This works for text - * files only. There is a rudimentary handling of UNICODE files. - * The comparison is case independent. - * - * @param pIOSystem IO System to work with - * @param file File name of the file - * @param tokens List of tokens to search for - * @param numTokens Size of the token array - * @param searchBytes Number of bytes to be searched for the tokens. - */ - static bool SearchFileHeaderForToken( - IOSystem* pIOSystem, - const std::string& file, - const char** tokens, - unsigned int numTokens, - unsigned int searchBytes = 200, - bool tokensSol = false, - bool noAlphaBeforeTokens = false); - - // ------------------------------------------------------------------- - /** @brief Check whether a file has a specific file extension - * @param pFile Input file - * @param ext0 Extension to check for. Lowercase characters only, no dot! - * @param ext1 Optional second extension - * @param ext2 Optional third extension - * @note Case-insensitive - */ - static bool SimpleExtensionCheck ( - const std::string& pFile, - const char* ext0, - const char* ext1 = NULL, - const char* ext2 = NULL); - - // ------------------------------------------------------------------- - /** @brief Extract file extension from a string - * @param pFile Input file - * @return Extension without trailing dot, all lowercase - */ - static std::string GetExtension ( - const std::string& pFile); - - // ------------------------------------------------------------------- - /** @brief Check whether a file starts with one or more magic tokens - * @param pFile Input file - * @param pIOHandler IO system to be used - * @param magic n magic tokens - * @params num Size of magic - * @param offset Offset from file start where tokens are located - * @param Size of one token, in bytes. Maximally 16 bytes. - * @return true if one of the given tokens was found - * - * @note For convenience, the check is also performed for the - * byte-swapped variant of all tokens (big endian). Only for - * tokens of size 2,4. - */ - static bool CheckMagicToken( - IOSystem* pIOHandler, - const std::string& pFile, - const void* magic, - unsigned int num, - unsigned int offset = 0, - unsigned int size = 4); - - // ------------------------------------------------------------------- - /** An utility for all text file loaders. It converts a file to our - * UTF8 character set. Errors are reported, but ignored. - * - * @param data File buffer to be converted to UTF8 data. The buffer - * is resized as appropriate. */ - static void ConvertToUTF8( - std::vector<char>& data); - - // ------------------------------------------------------------------- - /** An utility for all text file loaders. It converts a file from our - * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored. - * - * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer - * is resized as appropriate. */ - static void ConvertUTF8toISO8859_1( - std::string& data); - - // ------------------------------------------------------------------- - /// @brief Enum to define, if empty files are ok or not. - enum TextFileMode { - ALLOW_EMPTY, - FORBID_EMPTY - }; - - // ------------------------------------------------------------------- - /** Utility for text file loaders which copies the contents of the - * file into a memory buffer and converts it to our UTF8 - * representation. - * @param stream Stream to read from. - * @param data Output buffer to be resized and filled with the - * converted text file data. The buffer is terminated with - * a binary 0. - * @param mode Whether it is OK to load empty text files. */ - static void TextFileToBuffer( - IOStream* stream, - std::vector<char>& data, - TextFileMode mode = FORBID_EMPTY); - - // ------------------------------------------------------------------- - /** Utility function to move a std::vector into a aiScene array - * @param vec The vector to be moved - * @param out The output pointer to the allocated array. - * @param numOut The output count of elements copied. */ - template<typename T> - AI_FORCE_INLINE - static void CopyVector( - std::vector<T>& vec, - T*& out, - unsigned int& outLength) - { - outLength = unsigned(vec.size()); - if (outLength) { - out = new T[outLength]; - std::swap_ranges(vec.begin(), vec.end(), out); - } - } - -protected: - /// Error description in case there was one. - std::string m_ErrorText; - /// Currently set progress handler. - ProgressHandler* m_progress; -}; - - - -} // end of namespace Assimp - -#endif // AI_BASEIMPORTER_H_INC diff --git a/thirdparty/assimp/include/assimp/Bitmap.h b/thirdparty/assimp/include/assimp/Bitmap.h deleted file mode 100644 index 4c3f5a437b..0000000000 --- a/thirdparty/assimp/include/assimp/Bitmap.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Bitmap.h - * @brief Defines bitmap format helper for textures - * - * Used for file formats which embed their textures into the model file. - */ -#pragma once -#ifndef AI_BITMAP_H_INC -#define AI_BITMAP_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include "defs.h" -#include <stdint.h> -#include <cstddef> - -struct aiTexture; - -namespace Assimp { - -class IOStream; - -class ASSIMP_API Bitmap { -protected: - - struct Header { - uint16_t type; - uint32_t size; - uint16_t reserved1; - uint16_t reserved2; - uint32_t offset; - - // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. - // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). - static const std::size_t header_size = - sizeof(uint16_t) + // type - sizeof(uint32_t) + // size - sizeof(uint16_t) + // reserved1 - sizeof(uint16_t) + // reserved2 - sizeof(uint32_t); // offset - }; - - struct DIB { - uint32_t size; - int32_t width; - int32_t height; - uint16_t planes; - uint16_t bits_per_pixel; - uint32_t compression; - uint32_t image_size; - int32_t x_resolution; - int32_t y_resolution; - uint32_t nb_colors; - uint32_t nb_important_colors; - - // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. - // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). - static const std::size_t dib_size = - sizeof(uint32_t) + // size - sizeof(int32_t) + // width - sizeof(int32_t) + // height - sizeof(uint16_t) + // planes - sizeof(uint16_t) + // bits_per_pixel - sizeof(uint32_t) + // compression - sizeof(uint32_t) + // image_size - sizeof(int32_t) + // x_resolution - sizeof(int32_t) + // y_resolution - sizeof(uint32_t) + // nb_colors - sizeof(uint32_t); // nb_important_colors - }; - - static const std::size_t mBytesPerPixel = 4; - -public: - static void Save(aiTexture* texture, IOStream* file); - -protected: - static void WriteHeader(Header& header, IOStream* file); - static void WriteDIB(DIB& dib, IOStream* file); - static void WriteData(aiTexture* texture, IOStream* file); -}; - -} - -#endif // AI_BITMAP_H_INC diff --git a/thirdparty/assimp/include/assimp/BlobIOSystem.h b/thirdparty/assimp/include/assimp/BlobIOSystem.h deleted file mode 100644 index d005e5c119..0000000000 --- a/thirdparty/assimp/include/assimp/BlobIOSystem.h +++ /dev/null @@ -1,338 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Provides cheat implementations for IOSystem and IOStream to - * redirect exporter output to a blob chain.*/ - -#ifndef AI_BLOBIOSYSTEM_H_INCLUDED -#define AI_BLOBIOSYSTEM_H_INCLUDED - -#include <assimp/IOStream.hpp> -#include <assimp/cexport.h> -#include <assimp/IOSystem.hpp> -#include <assimp/DefaultLogger.hpp> -#include <stdint.h> -#include <set> -#include <vector> - -namespace Assimp { - class BlobIOSystem; - -// -------------------------------------------------------------------------------------------- -/** Redirect IOStream to a blob */ -// -------------------------------------------------------------------------------------------- -class BlobIOStream : public IOStream -{ -public: - - BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096) - : buffer() - , cur_size() - , file_size() - , cursor() - , initial(initial) - , file(file) - , creator(creator) - { - } - - - virtual ~BlobIOStream(); - -public: - - // ------------------------------------------------------------------- - aiExportDataBlob* GetBlob() - { - aiExportDataBlob* blob = new aiExportDataBlob(); - blob->size = file_size; - blob->data = buffer; - - buffer = NULL; - - return blob; - } - - -public: - - - // ------------------------------------------------------------------- - virtual size_t Read( void *, - size_t, - size_t ) - { - return 0; - } - - // ------------------------------------------------------------------- - virtual size_t Write(const void* pvBuffer, - size_t pSize, - size_t pCount) - { - pSize *= pCount; - if (cursor + pSize > cur_size) { - Grow(cursor + pSize); - } - - memcpy(buffer+cursor, pvBuffer, pSize); - cursor += pSize; - - file_size = std::max(file_size,cursor); - return pCount; - } - - // ------------------------------------------------------------------- - virtual aiReturn Seek(size_t pOffset, - aiOrigin pOrigin) - { - switch(pOrigin) - { - case aiOrigin_CUR: - cursor += pOffset; - break; - - case aiOrigin_END: - cursor = file_size - pOffset; - break; - - case aiOrigin_SET: - cursor = pOffset; - break; - - default: - return AI_FAILURE; - } - - if (cursor > file_size) { - Grow(cursor); - } - - file_size = std::max(cursor,file_size); - return AI_SUCCESS; - } - - // ------------------------------------------------------------------- - virtual size_t Tell() const - { - return cursor; - } - - // ------------------------------------------------------------------- - virtual size_t FileSize() const - { - return file_size; - } - - // ------------------------------------------------------------------- - virtual void Flush() - { - // ignore - } - - - -private: - - // ------------------------------------------------------------------- - void Grow(size_t need = 0) - { - // 1.5 and phi are very heap-friendly growth factors (the first - // allows for frequent re-use of heap blocks, the second - // forms a fibonacci sequence with similar characteristics - - // since this heavily depends on the heap implementation - // and other factors as well, i'll just go with 1.5 since - // it is quicker to compute). - size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); - - const uint8_t* const old = buffer; - buffer = new uint8_t[new_size]; - - if (old) { - memcpy(buffer,old,cur_size); - delete[] old; - } - - cur_size = new_size; - } - -private: - - uint8_t* buffer; - size_t cur_size,file_size, cursor, initial; - - const std::string file; - BlobIOSystem* const creator; -}; - - -#define AI_BLOBIO_MAGIC "$blobfile" - -// -------------------------------------------------------------------------------------------- -/** Redirect IOSystem to a blob */ -// -------------------------------------------------------------------------------------------- -class BlobIOSystem : public IOSystem -{ - - friend class BlobIOStream; - typedef std::pair<std::string, aiExportDataBlob*> BlobEntry; - -public: - - BlobIOSystem() - { - } - - virtual ~BlobIOSystem() - { - for(BlobEntry& blobby : blobs) { - delete blobby.second; - } - } - -public: - - // ------------------------------------------------------------------- - const char* GetMagicFileName() const - { - return AI_BLOBIO_MAGIC; - } - - - // ------------------------------------------------------------------- - aiExportDataBlob* GetBlobChain() - { - // one must be the master - aiExportDataBlob* master = NULL, *cur; - for(const BlobEntry& blobby : blobs) { - if (blobby.first == AI_BLOBIO_MAGIC) { - master = blobby.second; - break; - } - } - if (!master) { - ASSIMP_LOG_ERROR("BlobIOSystem: no data written or master file was not closed properly."); - return NULL; - } - - master->name.Set(""); - - cur = master; - for(const BlobEntry& blobby : blobs) { - if (blobby.second == master) { - continue; - } - - cur->next = blobby.second; - cur = cur->next; - - // extract the file extension from the file written - const std::string::size_type s = blobby.first.find_first_of('.'); - cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1)); - } - - // give up blob ownership - blobs.clear(); - return master; - } - -public: - - // ------------------------------------------------------------------- - virtual bool Exists( const char* pFile) const { - return created.find(std::string(pFile)) != created.end(); - } - - - // ------------------------------------------------------------------- - virtual char getOsSeparator() const { - return '/'; - } - - - // ------------------------------------------------------------------- - virtual IOStream* Open(const char* pFile, - const char* pMode) - { - if (pMode[0] != 'w') { - return NULL; - } - - created.insert(std::string(pFile)); - return new BlobIOStream(this,std::string(pFile)); - } - - // ------------------------------------------------------------------- - virtual void Close( IOStream* pFile) - { - delete pFile; - } - -private: - - // ------------------------------------------------------------------- - void OnDestruct(const std::string& filename, BlobIOStream* child) - { - // we don't know in which the files are closed, so we - // can't reliably say that the first must be the master - // file ... - blobs.push_back( BlobEntry(filename,child->GetBlob()) ); - } - -private: - std::set<std::string> created; - std::vector< BlobEntry > blobs; -}; - - -// -------------------------------------------------------------------------------------------- -BlobIOStream :: ~BlobIOStream() -{ - creator->OnDestruct(file,this); - delete[] buffer; -} - - -} // end Assimp - -#endif diff --git a/thirdparty/assimp/include/assimp/ByteSwapper.h b/thirdparty/assimp/include/assimp/ByteSwapper.h deleted file mode 100644 index 3f14c471a8..0000000000 --- a/thirdparty/assimp/include/assimp/ByteSwapper.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Helper class tp perform various byte oder swappings - (e.g. little to big endian) */ -#pragma once -#ifndef AI_BYTESWAPPER_H_INC -#define AI_BYTESWAPPER_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/ai_assert.h> -#include <assimp/types.h> -#include <stdint.h> - -#if _MSC_VER >= 1400 -#include <stdlib.h> -#endif - -namespace Assimp { -// -------------------------------------------------------------------------------------- -/** Defines some useful byte order swap routines. - * - * This is required to read big-endian model formats on little-endian machines, - * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */ -// -------------------------------------------------------------------------------------- -class ByteSwap { - ByteSwap() AI_NO_EXCEPT {} - -public: - - // ---------------------------------------------------------------------- - /** Swap two bytes of data - * @param[inout] _szOut A void* to save the reintcasts for the caller. */ - static inline void Swap2(void* _szOut) - { - ai_assert(_szOut); - -#if _MSC_VER >= 1400 - uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut); - *szOut = _byteswap_ushort(*szOut); -#else - uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); - std::swap(szOut[0],szOut[1]); -#endif - } - - // ---------------------------------------------------------------------- - /** Swap four bytes of data - * @param[inout] _szOut A void* to save the reintcasts for the caller. */ - static inline void Swap4(void* _szOut) - { - ai_assert(_szOut); - -#if _MSC_VER >= 1400 - uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut); - *szOut = _byteswap_ulong(*szOut); -#else - uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); - std::swap(szOut[0],szOut[3]); - std::swap(szOut[1],szOut[2]); -#endif - } - - // ---------------------------------------------------------------------- - /** Swap eight bytes of data - * @param[inout] _szOut A void* to save the reintcasts for the caller. */ - static inline void Swap8(void* _szOut) - { - ai_assert(_szOut); - -#if _MSC_VER >= 1400 - uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut); - *szOut = _byteswap_uint64(*szOut); -#else - uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); - std::swap(szOut[0],szOut[7]); - std::swap(szOut[1],szOut[6]); - std::swap(szOut[2],szOut[5]); - std::swap(szOut[3],szOut[4]); -#endif - } - - // ---------------------------------------------------------------------- - /** ByteSwap a float. Not a joke. - * @param[inout] fOut ehm. .. */ - static inline void Swap(float* fOut) { - Swap4(fOut); - } - - // ---------------------------------------------------------------------- - /** ByteSwap a double. Not a joke. - * @param[inout] fOut ehm. .. */ - static inline void Swap(double* fOut) { - Swap8(fOut); - } - - - // ---------------------------------------------------------------------- - /** ByteSwap an int16t. Not a joke. - * @param[inout] fOut ehm. .. */ - static inline void Swap(int16_t* fOut) { - Swap2(fOut); - } - - static inline void Swap(uint16_t* fOut) { - Swap2(fOut); - } - - // ---------------------------------------------------------------------- - /** ByteSwap an int32t. Not a joke. - * @param[inout] fOut ehm. .. */ - static inline void Swap(int32_t* fOut){ - Swap4(fOut); - } - - static inline void Swap(uint32_t* fOut){ - Swap4(fOut); - } - - // ---------------------------------------------------------------------- - /** ByteSwap an int64t. Not a joke. - * @param[inout] fOut ehm. .. */ - static inline void Swap(int64_t* fOut) { - Swap8(fOut); - } - - static inline void Swap(uint64_t* fOut) { - Swap8(fOut); - } - - // ---------------------------------------------------------------------- - //! Templatized ByteSwap - //! \returns param tOut as swapped - template<typename Type> - static inline Type Swapped(Type tOut) - { - return _swapper<Type,sizeof(Type)>()(tOut); - } - -private: - - template <typename T, size_t size> struct _swapper; -}; - -template <typename T> struct ByteSwap::_swapper<T,2> { - T operator() (T tOut) { - Swap2(&tOut); - return tOut; - } -}; - -template <typename T> struct ByteSwap::_swapper<T,4> { - T operator() (T tOut) { - Swap4(&tOut); - return tOut; - } -}; - -template <typename T> struct ByteSwap::_swapper<T,8> { - T operator() (T tOut) { - Swap8(&tOut); - return tOut; - } -}; - - -// -------------------------------------------------------------------------------------- -// ByteSwap macros for BigEndian/LittleEndian support -// -------------------------------------------------------------------------------------- -#if (defined AI_BUILD_BIG_ENDIAN) -# define AI_LE(t) (t) -# define AI_BE(t) ByteSwap::Swapped(t) -# define AI_LSWAP2(p) -# define AI_LSWAP4(p) -# define AI_LSWAP8(p) -# define AI_LSWAP2P(p) -# define AI_LSWAP4P(p) -# define AI_LSWAP8P(p) -# define LE_NCONST const -# define AI_SWAP2(p) ByteSwap::Swap2(&(p)) -# define AI_SWAP4(p) ByteSwap::Swap4(&(p)) -# define AI_SWAP8(p) ByteSwap::Swap8(&(p)) -# define AI_SWAP2P(p) ByteSwap::Swap2((p)) -# define AI_SWAP4P(p) ByteSwap::Swap4((p)) -# define AI_SWAP8P(p) ByteSwap::Swap8((p)) -# define BE_NCONST -#else -# define AI_BE(t) (t) -# define AI_LE(t) ByteSwap::Swapped(t) -# define AI_SWAP2(p) -# define AI_SWAP4(p) -# define AI_SWAP8(p) -# define AI_SWAP2P(p) -# define AI_SWAP4P(p) -# define AI_SWAP8P(p) -# define BE_NCONST const -# define AI_LSWAP2(p) ByteSwap::Swap2(&(p)) -# define AI_LSWAP4(p) ByteSwap::Swap4(&(p)) -# define AI_LSWAP8(p) ByteSwap::Swap8(&(p)) -# define AI_LSWAP2P(p) ByteSwap::Swap2((p)) -# define AI_LSWAP4P(p) ByteSwap::Swap4((p)) -# define AI_LSWAP8P(p) ByteSwap::Swap8((p)) -# define LE_NCONST -#endif - - -namespace Intern { - -// -------------------------------------------------------------------------------------------- -template <typename T, bool doit> -struct ByteSwapper { - void operator() (T* inout) { - ByteSwap::Swap(inout); - } -}; - -template <typename T> -struct ByteSwapper<T,false> { - void operator() (T*) { - } -}; - -// -------------------------------------------------------------------------------------------- -template <bool SwapEndianess, typename T, bool RuntimeSwitch> -struct Getter { - void operator() (T* inout, bool le) { -#ifdef AI_BUILD_BIG_ENDIAN - le = le; -#else - le = !le; -#endif - if (le) { - ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout); - } - else ByteSwapper<T,false> () (inout); - } -}; - -template <bool SwapEndianess, typename T> -struct Getter<SwapEndianess,T,false> { - - void operator() (T* inout, bool /*le*/) { - // static branch - ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout); - } -}; -} // end Intern -} // end Assimp - -#endif //!! AI_BYTESWAPPER_H_INC diff --git a/thirdparty/assimp/include/assimp/Compiler/poppack1.h b/thirdparty/assimp/include/assimp/Compiler/poppack1.h deleted file mode 100644 index e033bc1472..0000000000 --- a/thirdparty/assimp/include/assimp/Compiler/poppack1.h +++ /dev/null @@ -1,22 +0,0 @@ - -// =============================================================================== -// May be included multiple times - resets structure packing to the defaults -// for all supported compilers. Reverts the changes made by #include <pushpack1.h> -// -// Currently this works on the following compilers: -// MSVC 7,8,9 -// GCC -// BORLAND (complains about 'pack state changed but not reverted', but works) -// =============================================================================== - -#ifndef AI_PUSHPACK_IS_DEFINED -# error pushpack1.h must be included after poppack1.h -#endif - -// reset packing to the original value -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -# pragma pack( pop ) -#endif -#undef PACK_STRUCT - -#undef AI_PUSHPACK_IS_DEFINED diff --git a/thirdparty/assimp/include/assimp/Compiler/pstdint.h b/thirdparty/assimp/include/assimp/Compiler/pstdint.h deleted file mode 100644 index 4de4ce2a90..0000000000 --- a/thirdparty/assimp/include/assimp/Compiler/pstdint.h +++ /dev/null @@ -1,912 +0,0 @@ -/* A portable stdint.h - **************************************************************************** - * BSD License: - **************************************************************************** - * - * Copyright (c) 2005-2016 Paul Hsieh - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - **************************************************************************** - * - * Version 0.1.15.4 - * - * The ANSI C standard committee, for the C99 standard, specified the - * inclusion of a new standard include file called stdint.h. This is - * a very useful and long desired include file which contains several - * very precise definitions for integer scalar types that is - * critically important for making portable several classes of - * applications including cryptography, hashing, variable length - * integer libraries and so on. But for most developers its likely - * useful just for programming sanity. - * - * The problem is that some compiler vendors chose to ignore the C99 - * standard and some older compilers have no opportunity to be updated. - * Because of this situation, simply including stdint.h in your code - * makes it unportable. - * - * So that's what this file is all about. Its an attempt to build a - * single universal include file that works on as many platforms as - * possible to deliver what stdint.h is supposed to. Even compilers - * that already come with stdint.h can use this file instead without - * any loss of functionality. A few things that should be noted about - * this file: - * - * 1) It is not guaranteed to be portable and/or present an identical - * interface on all platforms. The extreme variability of the - * ANSI C standard makes this an impossibility right from the - * very get go. Its really only meant to be useful for the vast - * majority of platforms that possess the capability of - * implementing usefully and precisely defined, standard sized - * integer scalars. Systems which are not intrinsically 2s - * complement may produce invalid constants. - * - * 2) There is an unavoidable use of non-reserved symbols. - * - * 3) Other standard include files are invoked. - * - * 4) This file may come in conflict with future platforms that do - * include stdint.h. The hope is that one or the other can be - * used with no real difference. - * - * 5) In the current version, if your platform can't represent - * int32_t, int16_t and int8_t, it just dumps out with a compiler - * error. - * - * 6) 64 bit integers may or may not be defined. Test for their - * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. - * Note that this is different from the C99 specification which - * requires the existence of 64 bit support in the compiler. If - * this is not defined for your platform, yet it is capable of - * dealing with 64 bits then it is because this file has not yet - * been extended to cover all of your system's capabilities. - * - * 7) (u)intptr_t may or may not be defined. Test for its presence - * with the test: #ifdef PTRDIFF_MAX. If this is not defined - * for your platform, then it is because this file has not yet - * been extended to cover all of your system's capabilities, not - * because its optional. - * - * 8) The following might not been defined even if your platform is - * capable of defining it: - * - * WCHAR_MIN - * WCHAR_MAX - * (u)int64_t - * PTRDIFF_MIN - * PTRDIFF_MAX - * (u)intptr_t - * - * 9) The following have not been defined: - * - * WINT_MIN - * WINT_MAX - * - * 10) The criteria for defining (u)int_least(*)_t isn't clear, - * except for systems which don't have a type that precisely - * defined 8, 16, or 32 bit types (which this include file does - * not support anyways). Default definitions have been given. - * - * 11) The criteria for defining (u)int_fast(*)_t isn't something I - * would trust to any particular compiler vendor or the ANSI C - * committee. It is well known that "compatible systems" are - * commonly created that have very different performance - * characteristics from the systems they are compatible with, - * especially those whose vendors make both the compiler and the - * system. Default definitions have been given, but its strongly - * recommended that users never use these definitions for any - * reason (they do *NOT* deliver any serious guarantee of - * improved performance -- not in this file, nor any vendor's - * stdint.h). - * - * 12) The following macros: - * - * PRINTF_INTMAX_MODIFIER - * PRINTF_INT64_MODIFIER - * PRINTF_INT32_MODIFIER - * PRINTF_INT16_MODIFIER - * PRINTF_LEAST64_MODIFIER - * PRINTF_LEAST32_MODIFIER - * PRINTF_LEAST16_MODIFIER - * PRINTF_INTPTR_MODIFIER - * - * are strings which have been defined as the modifiers required - * for the "d", "u" and "x" printf formats to correctly output - * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, - * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. - * PRINTF_INTPTR_MODIFIER is not defined for some systems which - * provide their own stdint.h. PRINTF_INT64_MODIFIER is not - * defined if INT64_MAX is not defined. These are an extension - * beyond what C99 specifies must be in stdint.h. - * - * In addition, the following macros are defined: - * - * PRINTF_INTMAX_HEX_WIDTH - * PRINTF_INT64_HEX_WIDTH - * PRINTF_INT32_HEX_WIDTH - * PRINTF_INT16_HEX_WIDTH - * PRINTF_INT8_HEX_WIDTH - * PRINTF_INTMAX_DEC_WIDTH - * PRINTF_INT64_DEC_WIDTH - * PRINTF_INT32_DEC_WIDTH - * PRINTF_INT16_DEC_WIDTH - * PRINTF_UINT8_DEC_WIDTH - * PRINTF_UINTMAX_DEC_WIDTH - * PRINTF_UINT64_DEC_WIDTH - * PRINTF_UINT32_DEC_WIDTH - * PRINTF_UINT16_DEC_WIDTH - * PRINTF_UINT8_DEC_WIDTH - * - * Which specifies the maximum number of characters required to - * print the number of that type in either hexadecimal or decimal. - * These are an extension beyond what C99 specifies must be in - * stdint.h. - * - * Compilers tested (all with 0 warnings at their highest respective - * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 - * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio - * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 - * - * This file should be considered a work in progress. Suggestions for - * improvements, especially those which increase coverage are strongly - * encouraged. - * - * Acknowledgements - * - * The following people have made significant contributions to the - * development and testing of this file: - * - * Chris Howie - * John Steele Scott - * Dave Thorup - * John Dill - * Florian Wobbe - * Christopher Sean Morrison - * Mikkel Fahnoe Jorgensen - * - */ - -#include <stddef.h> -#include <limits.h> -#include <signal.h> - -/* - * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and - * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. - */ - -#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED) -#include <stdint.h> -#define _PSTDINT_H_INCLUDED -# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__)) -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "l" -# endif -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -# else -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# ifndef PRINTF_INT32_MODIFIER -# if (UINT_MAX == UINT32_MAX) -# define PRINTF_INT32_MODIFIER "" -# else -# define PRINTF_INT32_MODIFIER "l" -# endif -# endif -# endif -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "h" -# endif -# ifndef PRINTF_INTMAX_MODIFIER -# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER -# endif -# ifndef PRINTF_INT64_HEX_WIDTH -# define PRINTF_INT64_HEX_WIDTH "16" -# endif -# ifndef PRINTF_UINT64_HEX_WIDTH -# define PRINTF_UINT64_HEX_WIDTH "16" -# endif -# ifndef PRINTF_INT32_HEX_WIDTH -# define PRINTF_INT32_HEX_WIDTH "8" -# endif -# ifndef PRINTF_UINT32_HEX_WIDTH -# define PRINTF_UINT32_HEX_WIDTH "8" -# endif -# ifndef PRINTF_INT16_HEX_WIDTH -# define PRINTF_INT16_HEX_WIDTH "4" -# endif -# ifndef PRINTF_UINT16_HEX_WIDTH -# define PRINTF_UINT16_HEX_WIDTH "4" -# endif -# ifndef PRINTF_INT8_HEX_WIDTH -# define PRINTF_INT8_HEX_WIDTH "2" -# endif -# ifndef PRINTF_UINT8_HEX_WIDTH -# define PRINTF_UINT8_HEX_WIDTH "2" -# endif -# ifndef PRINTF_INT64_DEC_WIDTH -# define PRINTF_INT64_DEC_WIDTH "19" -# endif -# ifndef PRINTF_UINT64_DEC_WIDTH -# define PRINTF_UINT64_DEC_WIDTH "20" -# endif -# ifndef PRINTF_INT32_DEC_WIDTH -# define PRINTF_INT32_DEC_WIDTH "10" -# endif -# ifndef PRINTF_UINT32_DEC_WIDTH -# define PRINTF_UINT32_DEC_WIDTH "10" -# endif -# ifndef PRINTF_INT16_DEC_WIDTH -# define PRINTF_INT16_DEC_WIDTH "5" -# endif -# ifndef PRINTF_UINT16_DEC_WIDTH -# define PRINTF_UINT16_DEC_WIDTH "5" -# endif -# ifndef PRINTF_INT8_DEC_WIDTH -# define PRINTF_INT8_DEC_WIDTH "3" -# endif -# ifndef PRINTF_UINT8_DEC_WIDTH -# define PRINTF_UINT8_DEC_WIDTH "3" -# endif -# ifndef PRINTF_INTMAX_HEX_WIDTH -# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH -# endif -# ifndef PRINTF_UINTMAX_HEX_WIDTH -# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH -# endif -# ifndef PRINTF_INTMAX_DEC_WIDTH -# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH -# endif -# ifndef PRINTF_UINTMAX_DEC_WIDTH -# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH -# endif - -/* - * Something really weird is going on with Open Watcom. Just pull some of - * these duplicated definitions from Open Watcom's stdint.h file for now. - */ - -# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 -# if !defined (INT64_C) -# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) -# endif -# if !defined (UINT64_C) -# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) -# endif -# if !defined (INT32_C) -# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) -# endif -# if !defined (UINT32_C) -# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) -# endif -# if !defined (INT16_C) -# define INT16_C(x) (x) -# endif -# if !defined (UINT16_C) -# define UINT16_C(x) (x) -# endif -# if !defined (INT8_C) -# define INT8_C(x) (x) -# endif -# if !defined (UINT8_C) -# define UINT8_C(x) (x) -# endif -# if !defined (UINT64_MAX) -# define UINT64_MAX 18446744073709551615ULL -# endif -# if !defined (INT64_MAX) -# define INT64_MAX 9223372036854775807LL -# endif -# if !defined (UINT32_MAX) -# define UINT32_MAX 4294967295UL -# endif -# if !defined (INT32_MAX) -# define INT32_MAX 2147483647L -# endif -# if !defined (INTMAX_MAX) -# define INTMAX_MAX INT64_MAX -# endif -# if !defined (INTMAX_MIN) -# define INTMAX_MIN INT64_MIN -# endif -# endif -#endif - -/* - * I have no idea what is the truly correct thing to do on older Solaris. - * From some online discussions, this seems to be what is being - * recommended. For people who actually are developing on older Solaris, - * what I would like to know is, does this define all of the relevant - * macros of a complete stdint.h? Remember, in pstdint.h 64 bit is - * considered optional. - */ - -#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED) -#include <sys/inttypes.h> -#define _PSTDINT_H_INCLUDED -#endif - -#ifndef _PSTDINT_H_INCLUDED -#define _PSTDINT_H_INCLUDED - -#ifndef SIZE_MAX -# define SIZE_MAX (~(size_t)0) -#endif - -/* - * Deduce the type assignments from limits.h under the assumption that - * integer sizes in bits are powers of 2, and follow the ANSI - * definitions. - */ - -#ifndef UINT8_MAX -# define UINT8_MAX 0xff -#endif -#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks) -# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) - typedef unsigned char uint8_t; -# define UINT8_C(v) ((uint8_t) v) -# else -# error "Platform not supported" -# endif -#endif - -#ifndef INT8_MAX -# define INT8_MAX 0x7f -#endif -#ifndef INT8_MIN -# define INT8_MIN INT8_C(0x80) -#endif -#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks) -# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) - typedef signed char int8_t; -# define INT8_C(v) ((int8_t) v) -# else -# error "Platform not supported" -# endif -#endif - -#ifndef UINT16_MAX -# define UINT16_MAX 0xffff -#endif -#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks) -#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) - typedef unsigned int uint16_t; -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "" -# endif -# define UINT16_C(v) ((uint16_t) (v)) -#elif (USHRT_MAX == UINT16_MAX) - typedef unsigned short uint16_t; -# define UINT16_C(v) ((uint16_t) (v)) -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "h" -# endif -#else -#error "Platform not supported" -#endif -#endif - -#ifndef INT16_MAX -# define INT16_MAX 0x7fff -#endif -#ifndef INT16_MIN -# define INT16_MIN INT16_C(0x8000) -#endif -#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks) -#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) - typedef signed int int16_t; -# define INT16_C(v) ((int16_t) (v)) -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "" -# endif -#elif (SHRT_MAX == INT16_MAX) - typedef signed short int16_t; -# define INT16_C(v) ((int16_t) (v)) -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "h" -# endif -#else -#error "Platform not supported" -#endif -#endif - -#ifndef UINT32_MAX -# define UINT32_MAX (0xffffffffUL) -#endif -#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks) -#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) - typedef unsigned long uint32_t; -# define UINT32_C(v) v ## UL -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "l" -# endif -#elif (UINT_MAX == UINT32_MAX) - typedef unsigned int uint32_t; -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -# define UINT32_C(v) v ## U -#elif (USHRT_MAX == UINT32_MAX) - typedef unsigned short uint32_t; -# define UINT32_C(v) ((unsigned short) (v)) -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -#else -#error "Platform not supported" -#endif -#endif - -#ifndef INT32_MAX -# define INT32_MAX (0x7fffffffL) -#endif -#ifndef INT32_MIN -# define INT32_MIN INT32_C(0x80000000) -#endif -#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks) -#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) - typedef signed long int32_t; -# define INT32_C(v) v ## L -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "l" -# endif -#elif (INT_MAX == INT32_MAX) - typedef signed int int32_t; -# define INT32_C(v) v -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -#elif (SHRT_MAX == INT32_MAX) - typedef signed short int32_t; -# define INT32_C(v) ((short) (v)) -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -#else -#error "Platform not supported" -#endif -#endif - -/* - * The macro stdint_int64_defined is temporarily used to record - * whether or not 64 integer support is available. It must be - * defined for any 64 integer extensions for new platforms that are - * added. - */ - -#undef stdint_int64_defined -#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) -# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S) -# define stdint_int64_defined - typedef long long int64_t; - typedef unsigned long long uint64_t; -# define UINT64_C(v) v ## ULL -# define INT64_C(v) v ## LL -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# endif -#endif - -#if !defined (stdint_int64_defined) -# if defined(__GNUC__) && !defined(vxWorks) -# define stdint_int64_defined - __extension__ typedef long long int64_t; - __extension__ typedef unsigned long long uint64_t; -# define UINT64_C(v) v ## ULL -# define INT64_C(v) v ## LL -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) -# define stdint_int64_defined - typedef long long int64_t; - typedef unsigned long long uint64_t; -# define UINT64_C(v) v ## ULL -# define INT64_C(v) v ## LL -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) -# define stdint_int64_defined - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -# define UINT64_C(v) v ## UI64 -# define INT64_C(v) v ## I64 -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "I64" -# endif -# endif -#endif - -#if !defined (LONG_LONG_MAX) && defined (INT64_C) -# define LONG_LONG_MAX INT64_C (9223372036854775807) -#endif -#ifndef ULONG_LONG_MAX -# define ULONG_LONG_MAX UINT64_C (18446744073709551615) -#endif - -#if !defined (INT64_MAX) && defined (INT64_C) -# define INT64_MAX INT64_C (9223372036854775807) -#endif -#if !defined (INT64_MIN) && defined (INT64_C) -# define INT64_MIN INT64_C (-9223372036854775808) -#endif -#if !defined (UINT64_MAX) && defined (INT64_C) -# define UINT64_MAX UINT64_C (18446744073709551615) -#endif - -/* - * Width of hexadecimal for number field. - */ - -#ifndef PRINTF_INT64_HEX_WIDTH -# define PRINTF_INT64_HEX_WIDTH "16" -#endif -#ifndef PRINTF_INT32_HEX_WIDTH -# define PRINTF_INT32_HEX_WIDTH "8" -#endif -#ifndef PRINTF_INT16_HEX_WIDTH -# define PRINTF_INT16_HEX_WIDTH "4" -#endif -#ifndef PRINTF_INT8_HEX_WIDTH -# define PRINTF_INT8_HEX_WIDTH "2" -#endif -#ifndef PRINTF_INT64_DEC_WIDTH -# define PRINTF_INT64_DEC_WIDTH "19" -#endif -#ifndef PRINTF_INT32_DEC_WIDTH -# define PRINTF_INT32_DEC_WIDTH "10" -#endif -#ifndef PRINTF_INT16_DEC_WIDTH -# define PRINTF_INT16_DEC_WIDTH "5" -#endif -#ifndef PRINTF_INT8_DEC_WIDTH -# define PRINTF_INT8_DEC_WIDTH "3" -#endif -#ifndef PRINTF_UINT64_DEC_WIDTH -# define PRINTF_UINT64_DEC_WIDTH "20" -#endif -#ifndef PRINTF_UINT32_DEC_WIDTH -# define PRINTF_UINT32_DEC_WIDTH "10" -#endif -#ifndef PRINTF_UINT16_DEC_WIDTH -# define PRINTF_UINT16_DEC_WIDTH "5" -#endif -#ifndef PRINTF_UINT8_DEC_WIDTH -# define PRINTF_UINT8_DEC_WIDTH "3" -#endif - -/* - * Ok, lets not worry about 128 bit integers for now. Moore's law says - * we don't need to worry about that until about 2040 at which point - * we'll have bigger things to worry about. - */ - -#ifdef stdint_int64_defined - typedef int64_t intmax_t; - typedef uint64_t uintmax_t; -# define INTMAX_MAX INT64_MAX -# define INTMAX_MIN INT64_MIN -# define UINTMAX_MAX UINT64_MAX -# define UINTMAX_C(v) UINT64_C(v) -# define INTMAX_C(v) INT64_C(v) -# ifndef PRINTF_INTMAX_MODIFIER -# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER -# endif -# ifndef PRINTF_INTMAX_HEX_WIDTH -# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH -# endif -# ifndef PRINTF_INTMAX_DEC_WIDTH -# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH -# endif -#else - typedef int32_t intmax_t; - typedef uint32_t uintmax_t; -# define INTMAX_MAX INT32_MAX -# define UINTMAX_MAX UINT32_MAX -# define UINTMAX_C(v) UINT32_C(v) -# define INTMAX_C(v) INT32_C(v) -# ifndef PRINTF_INTMAX_MODIFIER -# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER -# endif -# ifndef PRINTF_INTMAX_HEX_WIDTH -# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH -# endif -# ifndef PRINTF_INTMAX_DEC_WIDTH -# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH -# endif -#endif - -/* - * Because this file currently only supports platforms which have - * precise powers of 2 as bit sizes for the default integers, the - * least definitions are all trivial. Its possible that a future - * version of this file could have different definitions. - */ - -#ifndef stdint_least_defined - typedef int8_t int_least8_t; - typedef uint8_t uint_least8_t; - typedef int16_t int_least16_t; - typedef uint16_t uint_least16_t; - typedef int32_t int_least32_t; - typedef uint32_t uint_least32_t; -# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER -# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER -# define UINT_LEAST8_MAX UINT8_MAX -# define INT_LEAST8_MAX INT8_MAX -# define UINT_LEAST16_MAX UINT16_MAX -# define INT_LEAST16_MAX INT16_MAX -# define UINT_LEAST32_MAX UINT32_MAX -# define INT_LEAST32_MAX INT32_MAX -# define INT_LEAST8_MIN INT8_MIN -# define INT_LEAST16_MIN INT16_MIN -# define INT_LEAST32_MIN INT32_MIN -# ifdef stdint_int64_defined - typedef int64_t int_least64_t; - typedef uint64_t uint_least64_t; -# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER -# define UINT_LEAST64_MAX UINT64_MAX -# define INT_LEAST64_MAX INT64_MAX -# define INT_LEAST64_MIN INT64_MIN -# endif -#endif -#undef stdint_least_defined - -/* - * The ANSI C committee pretending to know or specify anything about - * performance is the epitome of misguided arrogance. The mandate of - * this file is to *ONLY* ever support that absolute minimum - * definition of the fast integer types, for compatibility purposes. - * No extensions, and no attempt to suggest what may or may not be a - * faster integer type will ever be made in this file. Developers are - * warned to stay away from these types when using this or any other - * stdint.h. - */ - -typedef int_least8_t int_fast8_t; -typedef uint_least8_t uint_fast8_t; -typedef int_least16_t int_fast16_t; -typedef uint_least16_t uint_fast16_t; -typedef int_least32_t int_fast32_t; -typedef uint_least32_t uint_fast32_t; -#define UINT_FAST8_MAX UINT_LEAST8_MAX -#define INT_FAST8_MAX INT_LEAST8_MAX -#define UINT_FAST16_MAX UINT_LEAST16_MAX -#define INT_FAST16_MAX INT_LEAST16_MAX -#define UINT_FAST32_MAX UINT_LEAST32_MAX -#define INT_FAST32_MAX INT_LEAST32_MAX -#define INT_FAST8_MIN INT_LEAST8_MIN -#define INT_FAST16_MIN INT_LEAST16_MIN -#define INT_FAST32_MIN INT_LEAST32_MIN -#ifdef stdint_int64_defined - typedef int_least64_t int_fast64_t; - typedef uint_least64_t uint_fast64_t; -# define UINT_FAST64_MAX UINT_LEAST64_MAX -# define INT_FAST64_MAX INT_LEAST64_MAX -# define INT_FAST64_MIN INT_LEAST64_MIN -#endif - -#undef stdint_int64_defined - -/* - * Whatever piecemeal, per compiler thing we can do about the wchar_t - * type limits. - */ - -#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks) -# include <wchar.h> -# ifndef WCHAR_MIN -# define WCHAR_MIN 0 -# endif -# ifndef WCHAR_MAX -# define WCHAR_MAX ((wchar_t)-1) -# endif -#endif - -/* - * Whatever piecemeal, per compiler/platform thing we can do about the - * (u)intptr_t types and limits. - */ - -#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T) -# define STDINT_H_UINTPTR_T_DEFINED -#endif - -#ifndef STDINT_H_UINTPTR_T_DEFINED -# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__) -# define stdint_intptr_bits 64 -# elif defined (__WATCOMC__) || defined (__TURBOC__) -# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) -# define stdint_intptr_bits 16 -# else -# define stdint_intptr_bits 32 -# endif -# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__) -# define stdint_intptr_bits 32 -# elif defined (__INTEL_COMPILER) -/* TODO -- what did Intel do about x86-64? */ -# else -/* #error "This platform might not be supported yet" */ -# endif - -# ifdef stdint_intptr_bits -# define stdint_intptr_glue3_i(a,b,c) a##b##c -# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) -# ifndef PRINTF_INTPTR_MODIFIER -# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) -# endif -# ifndef PTRDIFF_MAX -# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) -# endif -# ifndef PTRDIFF_MIN -# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) -# endif -# ifndef UINTPTR_MAX -# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) -# endif -# ifndef INTPTR_MAX -# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) -# endif -# ifndef INTPTR_MIN -# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) -# endif -# ifndef INTPTR_C -# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) -# endif -# ifndef UINTPTR_C -# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) -# endif - typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; - typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; -# else -/* TODO -- This following is likely wrong for some platforms, and does - nothing for the definition of uintptr_t. */ - typedef ptrdiff_t intptr_t; -# endif -# define STDINT_H_UINTPTR_T_DEFINED -#endif - -/* - * Assumes sig_atomic_t is signed and we have a 2s complement machine. - */ - -#ifndef SIG_ATOMIC_MAX -# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) -#endif - -#endif - -#if defined (__TEST_PSTDINT_FOR_CORRECTNESS) - -/* - * Please compile with the maximum warning settings to make sure macros are - * not defined more than once. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#define glue3_aux(x,y,z) x ## y ## z -#define glue3(x,y,z) glue3_aux(x,y,z) - -#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0); -#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0); - -#define DECL(us,bits) glue3(DECL,us,) (bits) - -#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits) - -#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; } - -int main () { - int err_n = 0; - int err_first = 0; - DECL(I,8) - DECL(U,8) - DECL(I,16) - DECL(U,16) - DECL(I,32) - DECL(U,32) -#ifdef INT64_MAX - DECL(I,64) - DECL(U,64) -#endif - intmax_t imax = INTMAX_C(0); - uintmax_t umax = UINTMAX_C(0); - char str0[256], str1[256]; - - sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647)); - if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); - if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH)); - sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295)); - if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); - if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH)); -#ifdef INT64_MAX - sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807)); - if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); - if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1))); - sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591)); - if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); - if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1))); -#endif - - sprintf (str0, "%d %x\n", 0, ~0); - - sprintf (str1, "%d %x\n", i8, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1)); - sprintf (str1, "%u %x\n", u8, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1)); - sprintf (str1, "%d %x\n", i16, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1)); - sprintf (str1, "%u %x\n", u16, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1)); - sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1)); - sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1)); -#ifdef INT64_MAX - sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1)); -#endif - sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1)); - sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); - if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1)); - - TESTUMAX(8); - TESTUMAX(16); - TESTUMAX(32); -#ifdef INT64_MAX - TESTUMAX(64); -#endif - -#define STR(v) #v -#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v)); - if (err_n) { - printf ("pstdint.h is not correct. Please use sizes below to correct it:\n"); - } - - Q(int) - Q(unsigned) - Q(long int) - Q(short int) - Q(int8_t) - Q(int16_t) - Q(int32_t) -#ifdef INT64_MAX - Q(int64_t) -#endif - - return EXIT_SUCCESS; -} - -#endif diff --git a/thirdparty/assimp/include/assimp/Compiler/pushpack1.h b/thirdparty/assimp/include/assimp/Compiler/pushpack1.h deleted file mode 100644 index 4c9fbb857f..0000000000 --- a/thirdparty/assimp/include/assimp/Compiler/pushpack1.h +++ /dev/null @@ -1,43 +0,0 @@ - - -// =============================================================================== -// May be included multiple times - sets structure packing to 1 -// for all supported compilers. #include <poppack1.h> reverts the changes. -// -// Currently this works on the following compilers: -// MSVC 7,8,9 -// GCC -// BORLAND (complains about 'pack state changed but not reverted', but works) -// Clang -// -// -// USAGE: -// -// struct StructToBePacked { -// } PACK_STRUCT; -// -// =============================================================================== - -#ifdef AI_PUSHPACK_IS_DEFINED -# error poppack1.h must be included after pushpack1.h -#endif - -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -# pragma pack(push,1) -# define PACK_STRUCT -#elif defined( __GNUC__ ) || defined(__clang__) -# if !defined(HOST_MINGW) -# define PACK_STRUCT __attribute__((__packed__)) -# else -# define PACK_STRUCT __attribute__((gcc_struct, __packed__)) -# endif -#else -# error Compiler not supported -#endif - -#if defined(_MSC_VER) -// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop -# pragma warning (disable : 4103) -#endif - -#define AI_PUSHPACK_IS_DEFINED diff --git a/thirdparty/assimp/include/assimp/CreateAnimMesh.h b/thirdparty/assimp/include/assimp/CreateAnimMesh.h deleted file mode 100644 index 1266d1de11..0000000000 --- a/thirdparty/assimp/include/assimp/CreateAnimMesh.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file CreateAnimMesh.h - * Create AnimMesh from Mesh - */ -#pragma once -#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H -#define INCLUDED_AI_CREATE_ANIM_MESH_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/mesh.h> - -namespace Assimp { - -/** - * Create aiAnimMesh from aiMesh. - * @param mesh The input mesh to create an animated mesh from. - * @return The new created animated mesh. - */ -ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh); - -} // end of namespace Assimp - -#endif // INCLUDED_AI_CREATE_ANIM_MESH_H - diff --git a/thirdparty/assimp/include/assimp/DefaultIOStream.h b/thirdparty/assimp/include/assimp/DefaultIOStream.h deleted file mode 100644 index c6d382c1b5..0000000000 --- a/thirdparty/assimp/include/assimp/DefaultIOStream.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Default file I/O using fXXX()-family of functions */ -#pragma once -#ifndef AI_DEFAULTIOSTREAM_H_INC -#define AI_DEFAULTIOSTREAM_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <stdio.h> -#include <assimp/IOStream.hpp> -#include <assimp/importerdesc.h> -#include <assimp/Defines.h> - -namespace Assimp { - -// ---------------------------------------------------------------------------------- -//! @class DefaultIOStream -//! @brief Default IO implementation, use standard IO operations -//! @note An instance of this class can exist without a valid file handle -//! attached to it. All calls fail, but the instance can nevertheless be -//! used with no restrictions. -class ASSIMP_API DefaultIOStream : public IOStream { - friend class DefaultIOSystem; -#if __ANDROID__ -# if __ANDROID_API__ > 9 -# if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) - friend class AndroidJNIIOSystem; -# endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) -# endif // __ANDROID_API__ > 9 -#endif // __ANDROID__ - -protected: - DefaultIOStream() AI_NO_EXCEPT; - DefaultIOStream(FILE* pFile, const std::string &strFilename); - -public: - /** Destructor public to allow simple deletion to close the file. */ - ~DefaultIOStream (); - - // ------------------------------------------------------------------- - /// Read from stream - size_t Read(void* pvBuffer, - size_t pSize, - size_t pCount); - - // ------------------------------------------------------------------- - /// Write to stream - size_t Write(const void* pvBuffer, - size_t pSize, - size_t pCount); - - // ------------------------------------------------------------------- - /// Seek specific position - aiReturn Seek(size_t pOffset, - aiOrigin pOrigin); - - // ------------------------------------------------------------------- - /// Get current seek position - size_t Tell() const; - - // ------------------------------------------------------------------- - /// Get size of file - size_t FileSize() const; - - // ------------------------------------------------------------------- - /// Flush file contents - void Flush(); - -private: - FILE* mFile; - std::string mFilename; - mutable size_t mCachedSize; -}; - -// ---------------------------------------------------------------------------------- -AI_FORCE_INLINE -DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT -: mFile(nullptr) -, mFilename("") -, mCachedSize(SIZE_MAX) { - // empty -} - -// ---------------------------------------------------------------------------------- -AI_FORCE_INLINE -DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) -: mFile(pFile) -, mFilename(strFilename) -, mCachedSize(SIZE_MAX) { - // empty -} -// ---------------------------------------------------------------------------------- - -} // ns assimp - -#endif //!!AI_DEFAULTIOSTREAM_H_INC diff --git a/thirdparty/assimp/include/assimp/DefaultIOSystem.h b/thirdparty/assimp/include/assimp/DefaultIOSystem.h deleted file mode 100644 index 46f6d447c5..0000000000 --- a/thirdparty/assimp/include/assimp/DefaultIOSystem.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Default implementation of IOSystem using the standard C file functions */ -#pragma once -#ifndef AI_DEFAULTIOSYSTEM_H_INC -#define AI_DEFAULTIOSYSTEM_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/IOSystem.hpp> - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** Default implementation of IOSystem using the standard C file functions */ -class ASSIMP_API DefaultIOSystem : public IOSystem { -public: - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ - bool Exists( const char* pFile) const; - - // ------------------------------------------------------------------- - /** Returns the directory separator. */ - char getOsSeparator() const; - - // ------------------------------------------------------------------- - /** Open a new file with a given path. */ - IOStream* Open( const char* pFile, const char* pMode = "rb"); - - // ------------------------------------------------------------------- - /** Closes the given file and releases all resources associated with it. */ - void Close( IOStream* pFile); - - // ------------------------------------------------------------------- - /** Compare two paths */ - bool ComparePaths (const char* one, const char* second) const; - - /** @brief get the file name of a full filepath - * example: /tmp/archive.tar.gz -> archive.tar.gz - */ - static std::string fileName( const std::string &path ); - - /** @brief get the complete base name of a full filepath - * example: /tmp/archive.tar.gz -> archive.tar - */ - static std::string completeBaseName( const std::string &path); - - /** @brief get the path of a full filepath - * example: /tmp/archive.tar.gz -> /tmp/ - */ - static std::string absolutePath( const std::string &path); -}; - -} //!ns Assimp - -#endif //AI_DEFAULTIOSYSTEM_H_INC diff --git a/thirdparty/assimp/include/assimp/DefaultLogger.hpp b/thirdparty/assimp/include/assimp/DefaultLogger.hpp deleted file mode 100644 index 1946e250a6..0000000000 --- a/thirdparty/assimp/include/assimp/DefaultLogger.hpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -/** @file DefaultLogger.hpp -*/ - -#ifndef INCLUDED_AI_DEFAULTLOGGER -#define INCLUDED_AI_DEFAULTLOGGER - -#include "Logger.hpp" -#include "LogStream.hpp" -#include "NullLogger.hpp" -#include <vector> - -namespace Assimp { -// ------------------------------------------------------------------------------------ -class IOStream; -struct LogStreamInfo; - -/** default name of logfile */ -#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt" - -// ------------------------------------------------------------------------------------ -/** @brief CPP-API: Primary logging facility of Assimp. - * - * The library stores its primary #Logger as a static member of this class. - * #get() returns this primary logger. By default the underlying implementation is - * just a #NullLogger which rejects all log messages. By calling #create(), logging - * is turned on. To capture the log output multiple log streams (#LogStream) can be - * attach to the logger. Some default streams for common streaming locations (such as - * a file, std::cout, OutputDebugString()) are also provided. - * - * If you wish to customize the logging at an even deeper level supply your own - * implementation of #Logger to #set(). - * @note The whole logging stuff causes a small extra overhead for all imports. */ -class ASSIMP_API DefaultLogger : - public Logger { - -public: - - // ---------------------------------------------------------------------- - /** @brief Creates a logging instance. - * @param name Name for log file. Only valid in combination - * with the aiDefaultLogStream_FILE flag. - * @param severity Log severity, VERBOSE turns on debug messages - * @param defStreams Default log streams to be attached. Any bitwise - * combination of the aiDefaultLogStream enumerated values. - * If #aiDefaultLogStream_FILE is specified but an empty string is - * passed for 'name', no log file is created at all. - * @param io IOSystem to be used to open external files (such as the - * log file). Pass NULL to rely on the default implementation. - * This replaces the default #NullLogger with a #DefaultLogger instance. */ - static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME, - LogSeverity severity = NORMAL, - unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE, - IOSystem* io = NULL); - - // ---------------------------------------------------------------------- - /** @brief Setup a custom #Logger implementation. - * - * Use this if the provided #DefaultLogger class doesn't fit into - * your needs. If the provided message formatting is OK for you, - * it's much easier to use #create() and to attach your own custom - * output streams to it. - * @param logger Pass NULL to setup a default NullLogger*/ - static void set (Logger *logger); - - // ---------------------------------------------------------------------- - /** @brief Getter for singleton instance - * @return Only instance. This is never null, but it could be a - * NullLogger. Use isNullLogger to check this.*/ - static Logger *get(); - - // ---------------------------------------------------------------------- - /** @brief Return whether a #NullLogger is currently active - * @return true if the current logger is a #NullLogger. - * Use create() or set() to setup a logger that does actually do - * something else than just rejecting all log messages. */ - static bool isNullLogger(); - - // ---------------------------------------------------------------------- - /** @brief Kills the current singleton logger and replaces it with a - * #NullLogger instance. */ - static void kill(); - - // ---------------------------------------------------------------------- - /** @copydoc Logger::attachStream */ - bool attachStream(LogStream *pStream, - unsigned int severity); - - // ---------------------------------------------------------------------- - /** @copydoc Logger::detatchStream */ - bool detatchStream(LogStream *pStream, - unsigned int severity); - -private: - // ---------------------------------------------------------------------- - /** @briefPrivate construction for internal use by create(). - * @param severity Logging granularity */ - explicit DefaultLogger(LogSeverity severity); - - // ---------------------------------------------------------------------- - /** @briefDestructor */ - ~DefaultLogger(); - - /** @brief Logs debug infos, only been written when severity level VERBOSE is set */ - void OnDebug(const char* message); - - /** @brief Logs an info message */ - void OnInfo(const char* message); - - /** @brief Logs a warning message */ - void OnWarn(const char* message); - - /** @brief Logs an error message */ - void OnError(const char* message); - - // ---------------------------------------------------------------------- - /** @brief Writes a message to all streams */ - void WriteToStreams(const char* message, ErrorSeverity ErrorSev ); - - // ---------------------------------------------------------------------- - /** @brief Returns the thread id. - * @note This is an OS specific feature, if not supported, a - * zero will be returned. - */ - unsigned int GetThreadID(); - -private: - // Aliases for stream container - typedef std::vector<LogStreamInfo*> StreamArray; - typedef std::vector<LogStreamInfo*>::iterator StreamIt; - typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt; - - //! only logging instance - static Logger *m_pLogger; - static NullLogger s_pNullLogger; - - //! Attached streams - StreamArray m_StreamArray; - - bool noRepeatMsg; - char lastMsg[MAX_LOG_MESSAGE_LENGTH*2]; - size_t lastLen; -}; -// ------------------------------------------------------------------------------------ - -} // Namespace Assimp - -#endif // !! INCLUDED_AI_DEFAULTLOGGER diff --git a/thirdparty/assimp/include/assimp/Defines.h b/thirdparty/assimp/include/assimp/Defines.h deleted file mode 100644 index be3e2fafd6..0000000000 --- a/thirdparty/assimp/include/assimp/Defines.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#pragma once -#ifndef AI_DEFINES_H_INC -#define AI_DEFINES_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -// We need those constants, workaround for any platforms where nobody defined them yet -#if (!defined SIZE_MAX) -# define SIZE_MAX (~((size_t)0)) -#endif - -#if (!defined UINT_MAX) -# define UINT_MAX (~((unsigned int)0)) -#endif - -#endif // AI_DEINES_H_INC diff --git a/thirdparty/assimp/include/assimp/Exceptional.h b/thirdparty/assimp/include/assimp/Exceptional.h deleted file mode 100644 index 6bb6ce1e39..0000000000 --- a/thirdparty/assimp/include/assimp/Exceptional.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2008, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#pragma once -#ifndef AI_INCLUDED_EXCEPTIONAL_H -#define AI_INCLUDED_EXCEPTIONAL_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <stdexcept> -#include <assimp/DefaultIOStream.h> - -using std::runtime_error; - -#ifdef _MSC_VER -# pragma warning(disable : 4275) -#endif - -// --------------------------------------------------------------------------- -/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an - * unrecoverable error occurs while importing. Loading APIs return - * NULL instead of a valid aiScene then. */ -class DeadlyImportError : public runtime_error { -public: - /** Constructor with arguments */ - explicit DeadlyImportError( const std::string& errorText) - : runtime_error(errorText) { - // empty - } - -}; - -typedef DeadlyImportError DeadlyExportError; - -#ifdef _MSC_VER -# pragma warning(default : 4275) -#endif - -// --------------------------------------------------------------------------- -template <typename T> -struct ExceptionSwallower { - T operator ()() const { - return T(); - } -}; - -// --------------------------------------------------------------------------- -template <typename T> -struct ExceptionSwallower<T*> { - T* operator ()() const { - return nullptr; - } -}; - -// --------------------------------------------------------------------------- -template <> -struct ExceptionSwallower<aiReturn> { - aiReturn operator ()() const { - try { - throw; - } - catch (std::bad_alloc&) { - return aiReturn_OUTOFMEMORY; - } - catch (...) { - return aiReturn_FAILURE; - } - } -}; - -// --------------------------------------------------------------------------- -template <> -struct ExceptionSwallower<void> { - void operator ()() const { - return; - } -}; - -#define ASSIMP_BEGIN_EXCEPTION_REGION()\ -{\ - try { - -#define ASSIMP_END_EXCEPTION_REGION(type)\ - } catch(...) {\ - return ExceptionSwallower<type>()();\ - }\ -} - -#endif // AI_INCLUDED_EXCEPTIONAL_H diff --git a/thirdparty/assimp/include/assimp/Exporter.hpp b/thirdparty/assimp/include/assimp/Exporter.hpp deleted file mode 100644 index 2612e1f9d2..0000000000 --- a/thirdparty/assimp/include/assimp/Exporter.hpp +++ /dev/null @@ -1,509 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Exporter.hpp -* @brief Defines the CPP-API for the Assimp export interface -*/ -#pragma once -#ifndef AI_EXPORT_HPP_INC -#define AI_EXPORT_HPP_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifndef ASSIMP_BUILD_NO_EXPORT - -#include "cexport.h" -#include <map> - -namespace Assimp { - -class ExporterPimpl; -class IOSystem; -class ProgressHandler; - -// ---------------------------------------------------------------------------------- -/** CPP-API: The Exporter class forms an C++ interface to the export functionality - * of the Open Asset Import Library. Note that the export interface is available - * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined. - * - * The interface is modeled after the importer interface and mostly - * symmetric. The same rules for threading etc. apply. - * - * In a nutshell, there are two export interfaces: #Export, which writes the - * output file(s) either to the regular file system or to a user-supplied - * #IOSystem, and #ExportToBlob which returns a linked list of memory - * buffers (blob), each referring to one output file (in most cases - * there will be only one output file of course, but this extra complexity is - * needed since Assimp aims at supporting a wide range of file formats). - * - * #ExportToBlob is especially useful if you intend to work - * with the data in-memory. -*/ -class ASSIMP_API ExportProperties; - -class ASSIMP_API Exporter { -public: - /** Function pointer type of a Export worker function */ - typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*); - - /** Internal description of an Assimp export format option */ - struct ExportFormatEntry { - /// Public description structure to be returned by aiGetExportFormatDescription() - aiExportFormatDesc mDescription; - - // Worker function to do the actual exporting - fpExportFunc mExportFunction; - - // Post-processing steps to be executed PRIOR to invoking mExportFunction - unsigned int mEnforcePP; - - // Constructor to fill all entries - ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u) - { - mDescription.id = pId; - mDescription.description = pDesc; - mDescription.fileExtension = pExtension; - mExportFunction = pFunction; - mEnforcePP = pEnforcePP; - } - - ExportFormatEntry() : - mExportFunction() - , mEnforcePP() - { - mDescription.id = NULL; - mDescription.description = NULL; - mDescription.fileExtension = NULL; - } - }; - - /** - * @brief The class constructor. - */ - Exporter(); - - /** - * @brief The class destructor. - */ - ~Exporter(); - - // ------------------------------------------------------------------- - /** Supplies a custom IO handler to the exporter to use to open and - * access files. - * - * If you need #Export to use custom IO logic to access the files, - * you need to supply a custom implementation of IOSystem and - * IOFile to the exporter. - * - * #Exporter takes ownership of the object and will destroy it - * afterwards. The previously assigned handler will be deleted. - * Pass NULL to take again ownership of your IOSystem and reset Assimp - * to use its default implementation, which uses plain file IO. - * - * @param pIOHandler The IO handler to be used in all file accesses - * of the Importer. */ - void SetIOHandler( IOSystem* pIOHandler); - - // ------------------------------------------------------------------- - /** Retrieves the IO handler that is currently set. - * You can use #IsDefaultIOHandler() to check whether the returned - * interface is the default IO handler provided by ASSIMP. The default - * handler is active as long the application doesn't supply its own - * custom IO handler via #SetIOHandler(). - * @return A valid IOSystem interface, never NULL. */ - IOSystem* GetIOHandler() const; - - // ------------------------------------------------------------------- - /** Checks whether a default IO handler is active - * A default handler is active as long the application doesn't - * supply its own custom IO handler via #SetIOHandler(). - * @return true by default */ - bool IsDefaultIOHandler() const; - - // ------------------------------------------------------------------- - /** Supplies a custom progress handler to the exporter. This - * interface exposes an #Update() callback, which is called - * more or less periodically (please don't sue us if it - * isn't as periodically as you'd like it to have ...). - * This can be used to implement progress bars and loading - * timeouts. - * @param pHandler Progress callback interface. Pass nullptr to - * disable progress reporting. - * @note Progress handlers can be used to abort the loading - * at almost any time.*/ - void SetProgressHandler(ProgressHandler* pHandler); - - // ------------------------------------------------------------------- - /** Exports the given scene to a chosen file format. Returns the exported - * data as a binary blob which you can write into a file or something. - * When you're done with the data, simply let the #Exporter instance go - * out of scope to have it released automatically. - * @param pScene The scene to export. Stays in possession of the caller, - * is not changed by the function. - * @param pFormatId ID string to specify to which format you want to - * export to. Use - * #GetExportFormatCount / #GetExportFormatDescription to learn which - * export formats are available. - * @param pPreprocessing See the documentation for #Export - * @return the exported data or NULL in case of error. - * @note If the Exporter instance did already hold a blob from - * a previous call to #ExportToBlob, it will be disposed. - * Any IO handlers set via #SetIOHandler are ignored here. - * @note Use aiCopyScene() to get a modifiable copy of a previously - * imported scene. */ - const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId, - unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); - const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, - unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); - - // ------------------------------------------------------------------- - /** Convenience function to export directly to a file. Use - * #SetIOSystem to supply a custom IOSystem to gain fine-grained control - * about the output data flow of the export process. - * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL. - * @param pPath Full target file name. Target must be accessible. - * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated - * flags, but in reality only a subset of them makes sense here. Specifying - * 'preprocessing' flags is useful if the input scene does not conform to - * Assimp's default conventions as specified in the @link data Data Structures Page @endlink. - * In short, this means the geometry data should use a right-handed coordinate systems, face - * winding should be counter-clockwise and the UV coordinate origin is assumed to be in - * the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and - * #aiProcess_FlipWindingOrder flags are used in the import side to allow users - * to have those defaults automatically adapted to their conventions. Specifying those flags - * for exporting has the opposite effect, respectively. Some other of the - * #aiPostProcessSteps enumerated values may be useful as well, but you'll need - * to try out what their effect on the exported file is. Many formats impose - * their own restrictions on the structure of the geometry stored therein, - * so some preprocessing may have little or no effect at all, or may be - * redundant as exporters would apply them anyhow. A good example - * is triangulation - whilst you can enforce it by specifying - * the #aiProcess_Triangulate flag, most export formats support only - * triangulate data so they would run the step even if it wasn't requested. - * - * If assimp detects that the input scene was directly taken from the importer side of - * the library (i.e. not copied using aiCopyScene and potentially modified afterwards), - * any post-processing steps already applied to the scene will not be applied again, unless - * they show non-idempotent behavior (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and - * #aiProcess_FlipWindingOrder). - * @return AI_SUCCESS if everything was fine. - * @note Use aiCopyScene() to get a modifiable copy of a previously - * imported scene.*/ - aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, - unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); - aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, - unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); - - // ------------------------------------------------------------------- - /** Returns an error description of an error that occurred in #Export - * or #ExportToBlob - * - * Returns an empty string if no error occurred. - * @return A description of the last error, an empty string if no - * error occurred. The string is never NULL. - * - * @note The returned function remains valid until one of the - * following methods is called: #Export, #ExportToBlob, #FreeBlob */ - const char* GetErrorString() const; - - // ------------------------------------------------------------------- - /** Return the blob obtained from the last call to #ExportToBlob */ - const aiExportDataBlob* GetBlob() const; - - // ------------------------------------------------------------------- - /** Orphan the blob from the last call to #ExportToBlob. This means - * the caller takes ownership and is thus responsible for calling - * the C API function #aiReleaseExportBlob to release it. */ - const aiExportDataBlob* GetOrphanedBlob() const; - - // ------------------------------------------------------------------- - /** Frees the current blob. - * - * The function does nothing if no blob has previously been - * previously produced via #ExportToBlob. #FreeBlob is called - * automatically by the destructor. The only reason to call - * it manually would be to reclaim as much storage as possible - * without giving up the #Exporter instance yet. */ - void FreeBlob( ); - - // ------------------------------------------------------------------- - /** Returns the number of export file formats available in the current - * Assimp build. Use #Exporter::GetExportFormatDescription to - * retrieve infos of a specific export format. - * - * This includes built-in exporters as well as exporters registered - * using #RegisterExporter. - **/ - size_t GetExportFormatCount() const; - - // ------------------------------------------------------------------- - /** Returns a description of the nth export file format. Use # - * #Exporter::GetExportFormatCount to learn how many export - * formats are supported. - * - * The returned pointer is of static storage duration if the - * pIndex pertains to a built-in exporter (i.e. one not registered - * via #RegistrerExporter). It is restricted to the life-time of the - * #Exporter instance otherwise. - * - * @param pIndex Index of the export format to retrieve information - * for. Valid range is 0 to #Exporter::GetExportFormatCount - * @return A description of that specific export format. - * NULL if pIndex is out of range. */ - const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const; - - // ------------------------------------------------------------------- - /** Register a custom exporter. Custom export formats are limited to - * to the current #Exporter instance and do not affect the - * library globally. The indexes under which the format's - * export format description can be queried are assigned - * monotonously. - * @param desc Exporter description. - * @return aiReturn_SUCCESS if the export format was successfully - * registered. A common cause that would prevent an exporter - * from being registered is that its format id is already - * occupied by another format. */ - aiReturn RegisterExporter(const ExportFormatEntry& desc); - - // ------------------------------------------------------------------- - /** Remove an export format previously registered with #RegisterExporter - * from the #Exporter instance (this can also be used to drop - * built-in exporters because those are implicitly registered - * using #RegisterExporter). - * @param id Format id to be unregistered, this refers to the - * 'id' field of #aiExportFormatDesc. - * @note Calling this method on a format description not yet registered - * has no effect.*/ - void UnregisterExporter(const char* id); - -protected: - // Just because we don't want you to know how we're hacking around. - ExporterPimpl* pimpl; -}; - -class ASSIMP_API ExportProperties { -public: - // Data type to store the key hash - typedef unsigned int KeyType; - - // typedefs for our four configuration maps. - // We don't need more, so there is no need for a generic solution - typedef std::map<KeyType, int> IntPropertyMap; - typedef std::map<KeyType, ai_real> FloatPropertyMap; - typedef std::map<KeyType, std::string> StringPropertyMap; - typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap; - -public: - /** Standard constructor - * @see ExportProperties() - */ - ExportProperties(); - - // ------------------------------------------------------------------- - /** Copy constructor. - * - * This copies the configuration properties of another ExportProperties. - * @see ExportProperties(const ExportProperties& other) - */ - ExportProperties(const ExportProperties& other); - - // ------------------------------------------------------------------- - /** Set an integer configuration property. - * @param szName Name of the property. All supported properties - * are defined in the aiConfig.g header (all constants share the - * prefix AI_CONFIG_XXX and are simple strings). - * @param iValue New value of the property - * @return true if the property was set before. The new value replaces - * the previous value in this case. - * @note Property of different types (float, int, string ..) are kept - * on different stacks, so calling SetPropertyInteger() for a - * floating-point property has no effect - the loader will call - * GetPropertyFloat() to read the property, but it won't be there. - */ - bool SetPropertyInteger(const char* szName, int iValue); - - // ------------------------------------------------------------------- - /** Set a boolean configuration property. Boolean properties - * are stored on the integer stack internally so it's possible - * to set them via #SetPropertyBool and query them with - * #GetPropertyBool and vice versa. - * @see SetPropertyInteger() - */ - bool SetPropertyBool(const char* szName, bool value) { - return SetPropertyInteger(szName,value); - } - - // ------------------------------------------------------------------- - /** Set a floating-point configuration property. - * @see SetPropertyInteger() - */ - bool SetPropertyFloat(const char* szName, ai_real fValue); - - // ------------------------------------------------------------------- - /** Set a string configuration property. - * @see SetPropertyInteger() - */ - bool SetPropertyString(const char* szName, const std::string& sValue); - - // ------------------------------------------------------------------- - /** Set a matrix configuration property. - * @see SetPropertyInteger() - */ - bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue); - - // ------------------------------------------------------------------- - /** Get a configuration property. - * @param szName Name of the property. All supported properties - * are defined in the aiConfig.g header (all constants share the - * prefix AI_CONFIG_XXX). - * @param iErrorReturn Value that is returned if the property - * is not found. - * @return Current value of the property - * @note Property of different types (float, int, string ..) are kept - * on different lists, so calling SetPropertyInteger() for a - * floating-point property has no effect - the loader will call - * GetPropertyFloat() to read the property, but it won't be there. - */ - int GetPropertyInteger(const char* szName, - int iErrorReturn = 0xffffffff) const; - - // ------------------------------------------------------------------- - /** Get a boolean configuration property. Boolean properties - * are stored on the integer stack internally so it's possible - * to set them via #SetPropertyBool and query them with - * #GetPropertyBool and vice versa. - * @see GetPropertyInteger() - */ - bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const { - return GetPropertyInteger(szName,bErrorReturn)!=0; - } - - // ------------------------------------------------------------------- - /** Get a floating-point configuration property - * @see GetPropertyInteger() - */ - ai_real GetPropertyFloat(const char* szName, - ai_real fErrorReturn = 10e10f) const; - - // ------------------------------------------------------------------- - /** Get a string configuration property - * - * The return value remains valid until the property is modified. - * @see GetPropertyInteger() - */ - const std::string GetPropertyString(const char* szName, - const std::string& sErrorReturn = "") const; - - // ------------------------------------------------------------------- - /** Get a matrix configuration property - * - * The return value remains valid until the property is modified. - * @see GetPropertyInteger() - */ - const aiMatrix4x4 GetPropertyMatrix(const char* szName, - const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const; - - // ------------------------------------------------------------------- - /** Determine a integer configuration property has been set. - * @see HasPropertyInteger() - */ - bool HasPropertyInteger(const char* szName) const; - - /** Determine a boolean configuration property has been set. - * @see HasPropertyBool() - */ - bool HasPropertyBool(const char* szName) const; - - /** Determine a boolean configuration property has been set. - * @see HasPropertyFloat() - */ - bool HasPropertyFloat(const char* szName) const; - - /** Determine a String configuration property has been set. - * @see HasPropertyString() - */ - bool HasPropertyString(const char* szName) const; - - /** Determine a Matrix configuration property has been set. - * @see HasPropertyMatrix() - */ - bool HasPropertyMatrix(const char* szName) const; - -protected: - - /** List of integer properties */ - IntPropertyMap mIntProperties; - - /** List of floating-point properties */ - FloatPropertyMap mFloatProperties; - - /** List of string properties */ - StringPropertyMap mStringProperties; - - /** List of Matrix properties */ - MatrixPropertyMap mMatrixProperties; -}; - -// ---------------------------------------------------------------------------------- -inline -const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const std::string& pFormatId, - unsigned int pPreprocessing, const ExportProperties* pProperties) -{ - return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties); -} - -// ---------------------------------------------------------------------------------- -inline -aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, - const std::string& pPath, unsigned int pPreprocessing, - const ExportProperties* pProperties) -{ - return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties); -} - -} // namespace Assimp - -#endif // ASSIMP_BUILD_NO_EXPORT -#endif // AI_EXPORT_HPP_INC diff --git a/thirdparty/assimp/include/assimp/GenericProperty.h b/thirdparty/assimp/include/assimp/GenericProperty.h deleted file mode 100644 index 7796d595b8..0000000000 --- a/thirdparty/assimp/include/assimp/GenericProperty.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#pragma once -#ifndef AI_GENERIC_PROPERTY_H_INCLUDED -#define AI_GENERIC_PROPERTY_H_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/Importer.hpp> -#include <assimp/ai_assert.h> -#include <assimp/Hash.h> - -#include <map> - -// ------------------------------------------------------------------------------------------------ -template <class T> -inline -bool SetGenericProperty(std::map< unsigned int, T >& list, - const char* szName, const T& value) { - ai_assert(nullptr != szName); - const uint32_t hash = SuperFastHash(szName); - - typename std::map<unsigned int, T>::iterator it = list.find(hash); - if (it == list.end()) { - list.insert(std::pair<unsigned int, T>( hash, value )); - return false; - } - (*it).second = value; - - return true; -} - -// ------------------------------------------------------------------------------------------------ -template <class T> -inline -const T& GetGenericProperty(const std::map< unsigned int, T >& list, - const char* szName, const T& errorReturn) { - ai_assert(nullptr != szName); - const uint32_t hash = SuperFastHash(szName); - - typename std::map<unsigned int, T>::const_iterator it = list.find(hash); - if (it == list.end()) { - return errorReturn; - } - - return (*it).second; -} - -// ------------------------------------------------------------------------------------------------ -// Special version for pointer types - they will be deleted when replaced with another value -// passing NULL removes the whole property -template <class T> -inline -void SetGenericPropertyPtr(std::map< unsigned int, T* >& list, - const char* szName, T* value, bool* bWasExisting = nullptr ) { - ai_assert(nullptr != szName); - const uint32_t hash = SuperFastHash(szName); - - typename std::map<unsigned int, T*>::iterator it = list.find(hash); - if (it == list.end()) { - if (bWasExisting) { - *bWasExisting = false; - } - - list.insert(std::pair<unsigned int,T*>( hash, value )); - return; - } - if ((*it).second != value) { - delete (*it).second; - (*it).second = value; - } - if (!value) { - list.erase(it); - } - if (bWasExisting) { - *bWasExisting = true; - } -} - -// ------------------------------------------------------------------------------------------------ -template <class T> -inline -bool HasGenericProperty(const std::map< unsigned int, T >& list, - const char* szName) { - ai_assert(nullptr != szName); - const uint32_t hash = SuperFastHash(szName); - - typename std::map<unsigned int, T>::const_iterator it = list.find(hash); - if (it == list.end()) { - return false; - } - - return true; -} - -#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/Hash.h b/thirdparty/assimp/include/assimp/Hash.h deleted file mode 100644 index 9056440789..0000000000 --- a/thirdparty/assimp/include/assimp/Hash.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#pragma once -#ifndef AI_HASH_H_INCLUDED -#define AI_HASH_H_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <stdint.h> -#include <string.h> - -// ------------------------------------------------------------------------------------------------ -// Hashing function taken from -// http://www.azillionmonkeys.com/qed/hash.html -// (incremental version) -// -// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that -// Assimp's license is considered compatible with Pauls's derivative license as specified -// on his web page. -// -// (stdint.h should have been been included here) -// ------------------------------------------------------------------------------------------------ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif - -// ------------------------------------------------------------------------------------------------ -inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) { -uint32_t tmp; -int rem; - - if (!data) return 0; - if (!len)len = (uint32_t)::strlen(data); - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) { - hash += get16bits (data); - tmp = (get16bits (data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof (uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) { - case 3: hash += get16bits (data); - hash ^= hash << 16; - hash ^= data[sizeof (uint16_t)] << 18; - hash += hash >> 11; - break; - case 2: hash += get16bits (data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += *data; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} - -#endif // !! AI_HASH_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/IOStream.hpp b/thirdparty/assimp/include/assimp/IOStream.hpp deleted file mode 100644 index 39932cd949..0000000000 --- a/thirdparty/assimp/include/assimp/IOStream.hpp +++ /dev/null @@ -1,146 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file IOStream.hpp - * @brief File I/O wrappers for C++. - */ - -#pragma once -#ifndef AI_IOSTREAM_H_INC -#define AI_IOSTREAM_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -#ifndef __cplusplus -# error This header requires C++ to be used. aiFileIO.h is the \ - corresponding C interface. -#endif - -namespace Assimp { - -// ---------------------------------------------------------------------------------- -/** @brief CPP-API: Class to handle file I/O for C++ - * - * Derive an own implementation from this interface to provide custom IO handling - * to the Importer. If you implement this interface, be sure to also provide an - * implementation for IOSystem that creates instances of your custom IO class. -*/ -class ASSIMP_API IOStream -#ifndef SWIG - : public Intern::AllocateFromAssimpHeap -#endif -{ -protected: - /** Constructor protected, use IOSystem::Open() to create an instance. */ - IOStream() AI_NO_EXCEPT; - -public: - // ------------------------------------------------------------------- - /** @brief Destructor. Deleting the object closes the underlying file, - * alternatively you may use IOSystem::Close() to release the file. - */ - virtual ~IOStream(); - - // ------------------------------------------------------------------- - /** @brief Read from the file - * - * See fread() for more details - * This fails for write-only files */ - virtual size_t Read(void* pvBuffer, - size_t pSize, - size_t pCount) = 0; - - // ------------------------------------------------------------------- - /** @brief Write to the file - * - * See fwrite() for more details - * This fails for read-only files */ - virtual size_t Write(const void* pvBuffer, - size_t pSize, - size_t pCount) = 0; - - // ------------------------------------------------------------------- - /** @brief Set the read/write cursor of the file - * - * Note that the offset is _negative_ for aiOrigin_END. - * See fseek() for more details */ - virtual aiReturn Seek(size_t pOffset, - aiOrigin pOrigin) = 0; - - // ------------------------------------------------------------------- - /** @brief Get the current position of the read/write cursor - * - * See ftell() for more details */ - virtual size_t Tell() const = 0; - - // ------------------------------------------------------------------- - /** @brief Returns filesize - * Returns the filesize. */ - virtual size_t FileSize() const = 0; - - // ------------------------------------------------------------------- - /** @brief Flush the contents of the file buffer (for writers) - * See fflush() for more details. - */ - virtual void Flush() = 0; -}; //! class IOStream - -// ---------------------------------------------------------------------------------- -AI_FORCE_INLINE -IOStream::IOStream() AI_NO_EXCEPT { - // empty -} - -// ---------------------------------------------------------------------------------- -AI_FORCE_INLINE -IOStream::~IOStream() { - // empty -} -// ---------------------------------------------------------------------------------- - -} //!namespace Assimp - -#endif //!!AI_IOSTREAM_H_INC diff --git a/thirdparty/assimp/include/assimp/IOStreamBuffer.h b/thirdparty/assimp/include/assimp/IOStreamBuffer.h deleted file mode 100644 index 97c84b23e2..0000000000 --- a/thirdparty/assimp/include/assimp/IOStreamBuffer.h +++ /dev/null @@ -1,362 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#pragma once -#ifndef AI_IOSTREAMBUFFER_H_INC -#define AI_IOSTREAMBUFFER_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> -#include <assimp/IOStream.hpp> -#include <assimp/ParsingUtils.h> - -#include <vector> - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** - * Implementation of a cached stream buffer. - */ -template<class T> -class IOStreamBuffer { -public: - /// @brief The class constructor. - IOStreamBuffer( size_t cache = 4096 * 4096 ); - - /// @brief The class destructor. - ~IOStreamBuffer(); - - /// @brief Will open the cached access for a given stream. - /// @param stream The stream to cache. - /// @return true if successful. - bool open( IOStream *stream ); - - /// @brief Will close the cached access. - /// @return true if successful. - bool close(); - - /// @brief Returns the file-size. - /// @return The file-size. - size_t size() const; - - /// @brief Returns the cache size. - /// @return The cache size. - size_t cacheSize() const; - - /// @brief Will read the next block. - /// @return true if successful. - bool readNextBlock(); - - /// @brief Returns the number of blocks to read. - /// @return The number of blocks. - size_t getNumBlocks() const; - - /// @brief Returns the current block index. - /// @return The current block index. - size_t getCurrentBlockIndex() const; - - /// @brief Returns the current file pos. - /// @return The current file pos. - size_t getFilePos() const; - - /// @brief Will read the next line. - /// @param buffer The buffer for the next line. - /// @return true if successful. - bool getNextDataLine( std::vector<T> &buffer, T continuationToken ); - - /// @brief Will read the next line ascii or binary end line char. - /// @param buffer The buffer for the next line. - /// @return true if successful. - bool getNextLine(std::vector<T> &buffer); - - /// @brief Will read the next block. - /// @param buffer The buffer for the next block. - /// @return true if successful. - bool getNextBlock( std::vector<T> &buffer ); - -private: - IOStream *m_stream; - size_t m_filesize; - size_t m_cacheSize; - size_t m_numBlocks; - size_t m_blockIdx; - std::vector<T> m_cache; - size_t m_cachePos; - size_t m_filePos; -}; - -template<class T> -AI_FORCE_INLINE -IOStreamBuffer<T>::IOStreamBuffer( size_t cache ) -: m_stream( nullptr ) -, m_filesize( 0 ) -, m_cacheSize( cache ) -, m_numBlocks( 0 ) -, m_blockIdx( 0 ) -, m_cachePos( 0 ) -, m_filePos( 0 ) { - m_cache.resize( cache ); - std::fill( m_cache.begin(), m_cache.end(), '\n' ); -} - -template<class T> -AI_FORCE_INLINE -IOStreamBuffer<T>::~IOStreamBuffer() { - // empty -} - -template<class T> -AI_FORCE_INLINE -bool IOStreamBuffer<T>::open( IOStream *stream ) { - // file still opened! - if ( nullptr != m_stream ) { - return false; - } - - // Invalid stream pointer - if ( nullptr == stream ) { - return false; - } - - m_stream = stream; - m_filesize = m_stream->FileSize(); - if ( m_filesize == 0 ) { - return false; - } - if ( m_filesize < m_cacheSize ) { - m_cacheSize = m_filesize; - } - - m_numBlocks = m_filesize / m_cacheSize; - if ( ( m_filesize % m_cacheSize ) > 0 ) { - m_numBlocks++; - } - - return true; -} - -template<class T> -AI_FORCE_INLINE -bool IOStreamBuffer<T>::close() { - if ( nullptr == m_stream ) { - return false; - } - - // init counters and state vars - m_stream = nullptr; - m_filesize = 0; - m_numBlocks = 0; - m_blockIdx = 0; - m_cachePos = 0; - m_filePos = 0; - - return true; -} - -template<class T> -AI_FORCE_INLINE -size_t IOStreamBuffer<T>::size() const { - return m_filesize; -} - -template<class T> -AI_FORCE_INLINE -size_t IOStreamBuffer<T>::cacheSize() const { - return m_cacheSize; -} - -template<class T> -AI_FORCE_INLINE -bool IOStreamBuffer<T>::readNextBlock() { - m_stream->Seek( m_filePos, aiOrigin_SET ); - size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize ); - if ( readLen == 0 ) { - return false; - } - if ( readLen < m_cacheSize ) { - m_cacheSize = readLen; - } - m_filePos += m_cacheSize; - m_cachePos = 0; - m_blockIdx++; - - return true; -} - -template<class T> -AI_FORCE_INLINE -size_t IOStreamBuffer<T>::getNumBlocks() const { - return m_numBlocks; -} - -template<class T> -AI_FORCE_INLINE -size_t IOStreamBuffer<T>::getCurrentBlockIndex() const { - return m_blockIdx; -} - -template<class T> -AI_FORCE_INLINE -size_t IOStreamBuffer<T>::getFilePos() const { - return m_filePos; -} - -template<class T> -AI_FORCE_INLINE -bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) { - buffer.resize( m_cacheSize ); - if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) { - if ( !readNextBlock() ) { - return false; - } - } - - bool continuationFound( false ); - size_t i = 0; - for( ;; ) { - if ( continuationToken == m_cache[ m_cachePos ] ) { - continuationFound = true; - ++m_cachePos; - } - if ( IsLineEnd( m_cache[ m_cachePos ] ) ) { - if ( !continuationFound ) { - // the end of the data line - break; - } else { - // skip line end - while ( m_cache[m_cachePos] != '\n') { - ++m_cachePos; - } - ++m_cachePos; - continuationFound = false; - } - } - - buffer[ i ] = m_cache[ m_cachePos ]; - ++m_cachePos; - ++i; - if (m_cachePos >= size()) { - break; - } - if ( m_cachePos >= m_cacheSize ) { - if ( !readNextBlock() ) { - return false; - } - } - } - - buffer[ i ] = '\n'; - ++m_cachePos; - - return true; -} - -static AI_FORCE_INLINE -bool isEndOfCache( size_t pos, size_t cacheSize ) { - return ( pos == cacheSize ); -} - -template<class T> -AI_FORCE_INLINE -bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) { - buffer.resize(m_cacheSize); - if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) { - if (!readNextBlock()) { - return false; - } - } - - if (IsLineEnd(m_cache[m_cachePos])) { - // skip line end - while (m_cache[m_cachePos] != '\n') { - ++m_cachePos; - } - ++m_cachePos; - if ( isEndOfCache( m_cachePos, m_cacheSize ) ) { - if ( !readNextBlock() ) { - return false; - } - } - } - - size_t i( 0 ); - while (!IsLineEnd(m_cache[ m_cachePos ])) { - buffer[i] = m_cache[ m_cachePos ]; - ++m_cachePos; - ++i; - if (m_cachePos >= m_cacheSize) { - if (!readNextBlock()) { - return false; - } - } - } - buffer[i] = '\n'; - ++m_cachePos; - - return true; -} - -template<class T> -AI_FORCE_INLINE -bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) { - // Return the last block-value if getNextLine was used before - if ( 0 != m_cachePos ) { - buffer = std::vector<T>( m_cache.begin() + m_cachePos, m_cache.end() ); - m_cachePos = 0; - } else { - if ( !readNextBlock() ) { - return false; - } - - buffer = std::vector<T>(m_cache.begin(), m_cache.end()); - } - - return true; -} - -} // !ns Assimp - -#endif // AI_IOSTREAMBUFFER_H_INC diff --git a/thirdparty/assimp/include/assimp/IOSystem.hpp b/thirdparty/assimp/include/assimp/IOSystem.hpp deleted file mode 100644 index f1fb3b0c27..0000000000 --- a/thirdparty/assimp/include/assimp/IOSystem.hpp +++ /dev/null @@ -1,361 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file IOSystem.hpp - * @brief File system wrapper for C++. Inherit this class to supply - * custom file handling logic to the Import library. -*/ - -#pragma once -#ifndef AI_IOSYSTEM_H_INC -#define AI_IOSYSTEM_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifndef __cplusplus -# error This header requires C++ to be used. aiFileIO.h is the \ - corresponding C interface. -#endif - -#include "types.h" - -#ifdef _WIN32 -# include <direct.h> -# include <stdlib.h> -# include <stdio.h> -#else -# include <sys/stat.h> -# include <sys/types.h> -# include <unistd.h> -#endif // _WIN32 - -#include <vector> - -namespace Assimp { - - class IOStream; - -// --------------------------------------------------------------------------- -/** @brief CPP-API: Interface to the file system. - * - * Derive an own implementation from this interface to supply custom file handling - * to the importer library. If you implement this interface, you also want to - * supply a custom implementation for IOStream. - * - * @see Importer::SetIOHandler() - */ -class ASSIMP_API IOSystem -#ifndef SWIG - : public Intern::AllocateFromAssimpHeap -#endif -{ -public: - - // ------------------------------------------------------------------- - /** @brief Default constructor. - * - * Create an instance of your derived class and assign it to an - * #Assimp::Importer instance by calling Importer::SetIOHandler(). - */ - IOSystem() AI_NO_EXCEPT; - - // ------------------------------------------------------------------- - /** @brief Virtual destructor. - * - * It is safe to be called from within DLL Assimp, we're constructed - * on Assimp's heap. - */ - virtual ~IOSystem(); - - // ------------------------------------------------------------------- - /** @brief For backward compatibility - * @see Exists(const char*) - */ - AI_FORCE_INLINE bool Exists( const std::string& pFile) const; - - // ------------------------------------------------------------------- - /** @brief Tests for the existence of a file at the given path. - * - * @param pFile Path to the file - * @return true if there is a file with this path, else false. - */ - virtual bool Exists( const char* pFile) const = 0; - - // ------------------------------------------------------------------- - /** @brief Returns the system specific directory separator - * @return System specific directory separator - */ - virtual char getOsSeparator() const = 0; - - // ------------------------------------------------------------------- - /** @brief Open a new file with a given path. - * - * When the access to the file is finished, call Close() to release - * all associated resources (or the virtual dtor of the IOStream). - * - * @param pFile Path to the file - * @param pMode Desired file I/O mode. Required are: "wb", "w", "wt", - * "rb", "r", "rt". - * - * @return New IOStream interface allowing the lib to access - * the underlying file. - * @note When implementing this class to provide custom IO handling, - * you probably have to supply an own implementation of IOStream as well. - */ - virtual IOStream* Open(const char* pFile, - const char* pMode = "rb") = 0; - - // ------------------------------------------------------------------- - /** @brief For backward compatibility - * @see Open(const char*, const char*) - */ - inline IOStream* Open(const std::string& pFile, - const std::string& pMode = std::string("rb")); - - // ------------------------------------------------------------------- - /** @brief Closes the given file and releases all resources - * associated with it. - * @param pFile The file instance previously created by Open(). - */ - virtual void Close( IOStream* pFile) = 0; - - // ------------------------------------------------------------------- - /** @brief Compares two paths and check whether the point to - * identical files. - * - * The dummy implementation of this virtual member performs a - * case-insensitive comparison of the given strings. The default IO - * system implementation uses OS mechanisms to convert relative into - * absolute paths, so the result can be trusted. - * @param one First file - * @param second Second file - * @return true if the paths point to the same file. The file needn't - * be existing, however. - */ - virtual bool ComparePaths (const char* one, - const char* second) const; - - // ------------------------------------------------------------------- - /** @brief For backward compatibility - * @see ComparePaths(const char*, const char*) - */ - inline bool ComparePaths (const std::string& one, - const std::string& second) const; - - // ------------------------------------------------------------------- - /** @brief Pushes a new directory onto the directory stack. - * @param path Path to push onto the stack. - * @return True, when push was successful, false if path is empty. - */ - virtual bool PushDirectory( const std::string &path ); - - // ------------------------------------------------------------------- - /** @brief Returns the top directory from the stack. - * @return The directory on the top of the stack. - * Returns empty when no directory was pushed to the stack. - */ - virtual const std::string &CurrentDirectory() const; - - // ------------------------------------------------------------------- - /** @brief Returns the number of directories stored on the stack. - * @return The number of directories of the stack. - */ - virtual size_t StackSize() const; - - // ------------------------------------------------------------------- - /** @brief Pops the top directory from the stack. - * @return True, when a directory was on the stack. False if no - * directory was on the stack. - */ - virtual bool PopDirectory(); - - // ------------------------------------------------------------------- - /** @brief CReates an new directory at the given path. - * @param path [in] The path to create. - * @return True, when a directory was created. False if the directory - * cannot be created. - */ - virtual bool CreateDirectory( const std::string &path ); - - // ------------------------------------------------------------------- - /** @brief Will change the current directory to the given path. - * @param path [in] The path to change to. - * @return True, when the directory has changed successfully. - */ - virtual bool ChangeDirectory( const std::string &path ); - - virtual bool DeleteFile( const std::string &file ); - -private: - std::vector<std::string> m_pathStack; -}; - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -IOSystem::IOSystem() AI_NO_EXCEPT -: m_pathStack() { - // empty -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -IOSystem::~IOSystem() { - // empty -} - -// ---------------------------------------------------------------------------- -// For compatibility, the interface of some functions taking a std::string was -// changed to const char* to avoid crashes between binary incompatible STL -// versions. This code her is inlined, so it shouldn't cause any problems. -// ---------------------------------------------------------------------------- - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) { - // NOTE: - // For compatibility, interface was changed to const char* to - // avoid crashes between binary incompatible STL versions - return Open(pFile.c_str(),pMode.c_str()); -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::Exists( const std::string& pFile) const { - // NOTE: - // For compatibility, interface was changed to const char* to - // avoid crashes between binary incompatible STL versions - return Exists(pFile.c_str()); -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::ComparePaths (const std::string& one, const std::string& second) const { - // NOTE: - // For compatibility, interface was changed to const char* to - // avoid crashes between binary incompatible STL versions - return ComparePaths(one.c_str(),second.c_str()); -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::PushDirectory( const std::string &path ) { - if ( path.empty() ) { - return false; - } - - m_pathStack.push_back( path ); - - return true; -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -const std::string &IOSystem::CurrentDirectory() const { - if ( m_pathStack.empty() ) { - static const std::string Dummy(""); - return Dummy; - } - return m_pathStack[ m_pathStack.size()-1 ]; -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -size_t IOSystem::StackSize() const { - return m_pathStack.size(); -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::PopDirectory() { - if ( m_pathStack.empty() ) { - return false; - } - - m_pathStack.pop_back(); - - return true; -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::CreateDirectory( const std::string &path ) { - if ( path.empty() ) { - return false; - } - -#ifdef _WIN32 - return 0 != ::_mkdir( path.c_str() ); -#else - return 0 != ::mkdir( path.c_str(), 0777 ); -#endif // _WIN32 -} - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::ChangeDirectory( const std::string &path ) { - if ( path.empty() ) { - return false; - } - -#ifdef _WIN32 - return 0 != ::_chdir( path.c_str() ); -#else - return 0 != ::chdir( path.c_str() ); -#endif // _WIN32 -} - - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE -bool IOSystem::DeleteFile( const std::string &file ) { - if ( file.empty() ) { - return false; - } - const int retCode( ::remove( file.c_str() ) ); - return ( 0 == retCode ); -} -} //!ns Assimp - -#endif //AI_IOSYSTEM_H_INC diff --git a/thirdparty/assimp/include/assimp/Importer.hpp b/thirdparty/assimp/include/assimp/Importer.hpp deleted file mode 100644 index bf449a9a25..0000000000 --- a/thirdparty/assimp/include/assimp/Importer.hpp +++ /dev/null @@ -1,663 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Importer.hpp - * @brief Defines the C++-API to the Open Asset Import Library. - */ -#pragma once -#ifndef AI_ASSIMP_HPP_INC -#define AI_ASSIMP_HPP_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifndef __cplusplus -# error This header requires C++ to be used. Use assimp.h for plain C. -#endif // __cplusplus - -// Public ASSIMP data structures -#include <assimp/types.h> - -namespace Assimp { - // ======================================================================= - // Public interface to Assimp - class Importer; - class IOStream; - class IOSystem; - class ProgressHandler; - - // ======================================================================= - // Plugin development - // - // Include the following headers for the declarations: - // BaseImporter.h - // BaseProcess.h - class BaseImporter; - class BaseProcess; - class SharedPostProcessInfo; - class BatchLoader; - - // ======================================================================= - // Holy stuff, only for members of the high council of the Jedi. - class ImporterPimpl; -} //! namespace Assimp - -#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff - -struct aiScene; - -// importerdesc.h -struct aiImporterDesc; - -/** @namespace Assimp Assimp's CPP-API and all internal APIs */ -namespace Assimp { - -// ---------------------------------------------------------------------------------- -/** CPP-API: The Importer class forms an C++ interface to the functionality of the -* Open Asset Import Library. -* -* Create an object of this class and call ReadFile() to import a file. -* If the import succeeds, the function returns a pointer to the imported data. -* The data remains property of the object, it is intended to be accessed -* read-only. The imported data will be destroyed along with the Importer -* object. If the import fails, ReadFile() returns a NULL pointer. In this -* case you can retrieve a human-readable error description be calling -* GetErrorString(). You can call ReadFile() multiple times with a single Importer -* instance. Actually, constructing Importer objects involves quite many -* allocations and may take some time, so it's better to reuse them as often as -* possible. -* -* If you need the Importer to do custom file handling to access the files, -* implement IOSystem and IOStream and supply an instance of your custom -* IOSystem implementation by calling SetIOHandler() before calling ReadFile(). -* If you do not assign a custion IO handler, a default handler using the -* standard C++ IO logic will be used. -* -* @note One Importer instance is not thread-safe. If you use multiple -* threads for loading, each thread should maintain its own Importer instance. -*/ -class ASSIMP_API Importer { -public: - /** - * @brief The upper limit for hints. - */ - static const unsigned int MaxLenHint = 200; - -public: - - // ------------------------------------------------------------------- - /** Constructor. Creates an empty importer object. - * - * Call ReadFile() to start the import process. The configuration - * property table is initially empty. - */ - Importer(); - - // ------------------------------------------------------------------- - /** Copy constructor. - * - * This copies the configuration properties of another Importer. - * If this Importer owns a scene it won't be copied. - * Call ReadFile() to start the import process. - */ - Importer(const Importer& other)=delete; - - // ------------------------------------------------------------------- - /** Assignment operator has been deleted - */ - Importer &operator=(const Importer &) = delete; - - // ------------------------------------------------------------------- - /** Destructor. The object kept ownership of the imported data, - * which now will be destroyed along with the object. - */ - ~Importer(); - - - // ------------------------------------------------------------------- - /** Registers a new loader. - * - * @param pImp Importer to be added. The Importer instance takes - * ownership of the pointer, so it will be automatically deleted - * with the Importer instance. - * @return AI_SUCCESS if the loader has been added. The registration - * fails if there is already a loader for a specific file extension. - */ - aiReturn RegisterLoader(BaseImporter* pImp); - - // ------------------------------------------------------------------- - /** Unregisters a loader. - * - * @param pImp Importer to be unregistered. - * @return AI_SUCCESS if the loader has been removed. The function - * fails if the loader is currently in use (this could happen - * if the #Importer instance is used by more than one thread) or - * if it has not yet been registered. - */ - aiReturn UnregisterLoader(BaseImporter* pImp); - - // ------------------------------------------------------------------- - /** Registers a new post-process step. - * - * At the moment, there's a small limitation: new post processing - * steps are added to end of the list, or in other words, executed - * last, after all built-in steps. - * @param pImp Post-process step to be added. The Importer instance - * takes ownership of the pointer, so it will be automatically - * deleted with the Importer instance. - * @return AI_SUCCESS if the step has been added correctly. - */ - aiReturn RegisterPPStep(BaseProcess* pImp); - - // ------------------------------------------------------------------- - /** Unregisters a post-process step. - * - * @param pImp Step to be unregistered. - * @return AI_SUCCESS if the step has been removed. The function - * fails if the step is currently in use (this could happen - * if the #Importer instance is used by more than one thread) or - * if it has not yet been registered. - */ - aiReturn UnregisterPPStep(BaseProcess* pImp); - - // ------------------------------------------------------------------- - /** Set an integer configuration property. - * @param szName Name of the property. All supported properties - * are defined in the aiConfig.g header (all constants share the - * prefix AI_CONFIG_XXX and are simple strings). - * @param iValue New value of the property - * @return true if the property was set before. The new value replaces - * the previous value in this case. - * @note Property of different types (float, int, string ..) are kept - * on different stacks, so calling SetPropertyInteger() for a - * floating-point property has no effect - the loader will call - * GetPropertyFloat() to read the property, but it won't be there. - */ - bool SetPropertyInteger(const char* szName, int iValue); - - // ------------------------------------------------------------------- - /** Set a boolean configuration property. Boolean properties - * are stored on the integer stack internally so it's possible - * to set them via #SetPropertyBool and query them with - * #GetPropertyBool and vice versa. - * @see SetPropertyInteger() - */ - bool SetPropertyBool(const char* szName, bool value) { - return SetPropertyInteger(szName,value); - } - - // ------------------------------------------------------------------- - /** Set a floating-point configuration property. - * @see SetPropertyInteger() - */ - bool SetPropertyFloat(const char* szName, ai_real fValue); - - // ------------------------------------------------------------------- - /** Set a string configuration property. - * @see SetPropertyInteger() - */ - bool SetPropertyString(const char* szName, const std::string& sValue); - - // ------------------------------------------------------------------- - /** Set a matrix configuration property. - * @see SetPropertyInteger() - */ - bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue); - - // ------------------------------------------------------------------- - /** Get a configuration property. - * @param szName Name of the property. All supported properties - * are defined in the aiConfig.g header (all constants share the - * prefix AI_CONFIG_XXX). - * @param iErrorReturn Value that is returned if the property - * is not found. - * @return Current value of the property - * @note Property of different types (float, int, string ..) are kept - * on different lists, so calling SetPropertyInteger() for a - * floating-point property has no effect - the loader will call - * GetPropertyFloat() to read the property, but it won't be there. - */ - int GetPropertyInteger(const char* szName, - int iErrorReturn = 0xffffffff) const; - - // ------------------------------------------------------------------- - /** Get a boolean configuration property. Boolean properties - * are stored on the integer stack internally so it's possible - * to set them via #SetPropertyBool and query them with - * #GetPropertyBool and vice versa. - * @see GetPropertyInteger() - */ - bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const { - return GetPropertyInteger(szName,bErrorReturn)!=0; - } - - // ------------------------------------------------------------------- - /** Get a floating-point configuration property - * @see GetPropertyInteger() - */ - ai_real GetPropertyFloat(const char* szName, - ai_real fErrorReturn = 10e10) const; - - // ------------------------------------------------------------------- - /** Get a string configuration property - * - * The return value remains valid until the property is modified. - * @see GetPropertyInteger() - */ - const std::string GetPropertyString(const char* szName, - const std::string& sErrorReturn = "") const; - - // ------------------------------------------------------------------- - /** Get a matrix configuration property - * - * The return value remains valid until the property is modified. - * @see GetPropertyInteger() - */ - const aiMatrix4x4 GetPropertyMatrix(const char* szName, - const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const; - - // ------------------------------------------------------------------- - /** Supplies a custom IO handler to the importer to use to open and - * access files. If you need the importer to use custom IO logic to - * access the files, you need to provide a custom implementation of - * IOSystem and IOFile to the importer. Then create an instance of - * your custom IOSystem implementation and supply it by this function. - * - * The Importer takes ownership of the object and will destroy it - * afterwards. The previously assigned handler will be deleted. - * Pass NULL to take again ownership of your IOSystem and reset Assimp - * to use its default implementation. - * - * @param pIOHandler The IO handler to be used in all file accesses - * of the Importer. - */ - void SetIOHandler( IOSystem* pIOHandler); - - // ------------------------------------------------------------------- - /** Retrieves the IO handler that is currently set. - * You can use #IsDefaultIOHandler() to check whether the returned - * interface is the default IO handler provided by ASSIMP. The default - * handler is active as long the application doesn't supply its own - * custom IO handler via #SetIOHandler(). - * @return A valid IOSystem interface, never NULL. - */ - IOSystem* GetIOHandler() const; - - // ------------------------------------------------------------------- - /** Checks whether a default IO handler is active - * A default handler is active as long the application doesn't - * supply its own custom IO handler via #SetIOHandler(). - * @return true by default - */ - bool IsDefaultIOHandler() const; - - // ------------------------------------------------------------------- - /** Supplies a custom progress handler to the importer. This - * interface exposes an #Update() callback, which is called - * more or less periodically (please don't sue us if it - * isn't as periodically as you'd like it to have ...). - * This can be used to implement progress bars and loading - * timeouts. - * @param pHandler Progress callback interface. Pass NULL to - * disable progress reporting. - * @note Progress handlers can be used to abort the loading - * at almost any time.*/ - void SetProgressHandler ( ProgressHandler* pHandler ); - - // ------------------------------------------------------------------- - /** Retrieves the progress handler that is currently set. - * You can use #IsDefaultProgressHandler() to check whether the returned - * interface is the default handler provided by ASSIMP. The default - * handler is active as long the application doesn't supply its own - * custom handler via #SetProgressHandler(). - * @return A valid ProgressHandler interface, never NULL. - */ - ProgressHandler* GetProgressHandler() const; - - // ------------------------------------------------------------------- - /** Checks whether a default progress handler is active - * A default handler is active as long the application doesn't - * supply its own custom progress handler via #SetProgressHandler(). - * @return true by default - */ - bool IsDefaultProgressHandler() const; - - // ------------------------------------------------------------------- - /** @brief Check whether a given set of post-processing flags - * is supported. - * - * Some flags are mutually exclusive, others are probably - * not available because your excluded them from your - * Assimp builds. Calling this function is recommended if - * you're unsure. - * - * @param pFlags Bitwise combination of the aiPostProcess flags. - * @return true if this flag combination is fine. - */ - bool ValidateFlags(unsigned int pFlags) const; - - // ------------------------------------------------------------------- - /** Reads the given file and returns its contents if successful. - * - * If the call succeeds, the contents of the file are returned as a - * pointer to an aiScene object. The returned data is intended to be - * read-only, the importer object keeps ownership of the data and will - * destroy it upon destruction. If the import fails, NULL is returned. - * A human-readable error description can be retrieved by calling - * GetErrorString(). The previous scene will be deleted during this call. - * @param pFile Path and filename to the file to be imported. - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. If you wish to inspect the imported - * scene first in order to fine-tune your post-processing setup, - * consider to use #ApplyPostProcessing(). - * @return A pointer to the imported data, NULL if the import failed. - * The pointer to the scene remains in possession of the Importer - * instance. Use GetOrphanedScene() to take ownership of it. - * - * @note Assimp is able to determine the file format of a file - * automatically. - */ - const aiScene* ReadFile( - const char* pFile, - unsigned int pFlags); - - // ------------------------------------------------------------------- - /** Reads the given file from a memory buffer and returns its - * contents if successful. - * - * If the call succeeds, the contents of the file are returned as a - * pointer to an aiScene object. The returned data is intended to be - * read-only, the importer object keeps ownership of the data and will - * destroy it upon destruction. If the import fails, NULL is returned. - * A human-readable error description can be retrieved by calling - * GetErrorString(). The previous scene will be deleted during this call. - * Calling this method doesn't affect the active IOSystem. - * @param pBuffer Pointer to the file data - * @param pLength Length of pBuffer, in bytes - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. If you wish to inspect the imported - * scene first in order to fine-tune your post-processing setup, - * consider to use #ApplyPostProcessing(). - * @param pHint An additional hint to the library. If this is a non - * empty string, the library looks for a loader to support - * the file extension specified by pHint and passes the file to - * the first matching loader. If this loader is unable to completely - * the request, the library continues and tries to determine the - * file format on its own, a task that may or may not be successful. - * Check the return value, and you'll know ... - * @return A pointer to the imported data, NULL if the import failed. - * The pointer to the scene remains in possession of the Importer - * instance. Use GetOrphanedScene() to take ownership of it. - * - * @note This is a straightforward way to decode models from memory - * buffers, but it doesn't handle model formats that spread their - * data across multiple files or even directories. Examples include - * OBJ or MD3, which outsource parts of their material info into - * external scripts. If you need full functionality, provide - * a custom IOSystem to make Assimp find these files and use - * the regular ReadFile() API. - */ - const aiScene* ReadFileFromMemory( - const void* pBuffer, - size_t pLength, - unsigned int pFlags, - const char* pHint = ""); - - // ------------------------------------------------------------------- - /** Apply post-processing to an already-imported scene. - * - * This is strictly equivalent to calling #ReadFile() with the same - * flags. However, you can use this separate function to inspect - * the imported scene first to fine-tune your post-processing setup. - * @param pFlags Provide a bitwise combination of the - * #aiPostProcessSteps flags. - * @return A pointer to the post-processed data. This is still the - * same as the pointer returned by #ReadFile(). However, if - * post-processing fails, the scene could now be NULL. - * That's quite a rare case, post processing steps are not really - * designed to 'fail'. To be exact, the #aiProcess_ValidateDS - * flag is currently the only post processing step which can actually - * cause the scene to be reset to NULL. - * - * @note The method does nothing if no scene is currently bound - * to the #Importer instance. */ - const aiScene* ApplyPostProcessing(unsigned int pFlags); - - const aiScene* ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation ); - - // ------------------------------------------------------------------- - /** @brief Reads the given file and returns its contents if successful. - * - * This function is provided for backward compatibility. - * See the const char* version for detailed docs. - * @see ReadFile(const char*, pFlags) */ - const aiScene* ReadFile( - const std::string& pFile, - unsigned int pFlags); - - // ------------------------------------------------------------------- - /** Frees the current scene. - * - * The function does nothing if no scene has previously been - * read via ReadFile(). FreeScene() is called automatically by the - * destructor and ReadFile() itself. */ - void FreeScene( ); - - // ------------------------------------------------------------------- - /** Returns an error description of an error that occurred in ReadFile(). - * - * Returns an empty string if no error occurred. - * @return A description of the last error, an empty string if no - * error occurred. The string is never NULL. - * - * @note The returned function remains valid until one of the - * following methods is called: #ReadFile(), #FreeScene(). */ - const char* GetErrorString() const; - - // ------------------------------------------------------------------- - /** Returns the scene loaded by the last successful call to ReadFile() - * - * @return Current scene or NULL if there is currently no scene loaded */ - const aiScene* GetScene() const; - - // ------------------------------------------------------------------- - /** Returns the scene loaded by the last successful call to ReadFile() - * and releases the scene from the ownership of the Importer - * instance. The application is now responsible for deleting the - * scene. Any further calls to GetScene() or GetOrphanedScene() - * will return NULL - until a new scene has been loaded via ReadFile(). - * - * @return Current scene or NULL if there is currently no scene loaded - * @note Use this method with maximal caution, and only if you have to. - * By design, aiScene's are exclusively maintained, allocated and - * deallocated by Assimp and no one else. The reasoning behind this - * is the golden rule that deallocations should always be done - * by the module that did the original allocation because heaps - * are not necessarily shared. GetOrphanedScene() enforces you - * to delete the returned scene by yourself, but this will only - * be fine if and only if you're using the same heap as assimp. - * On Windows, it's typically fine provided everything is linked - * against the multithreaded-dll version of the runtime library. - * It will work as well for static linkage with Assimp.*/ - aiScene* GetOrphanedScene(); - - // ------------------------------------------------------------------- - /** Returns whether a given file extension is supported by ASSIMP. - * - * @param szExtension Extension to be checked. - * Must include a trailing dot '.'. Example: ".3ds", ".md3". - * Cases-insensitive. - * @return true if the extension is supported, false otherwise */ - bool IsExtensionSupported(const char* szExtension) const; - - // ------------------------------------------------------------------- - /** @brief Returns whether a given file extension is supported by ASSIMP. - * - * This function is provided for backward compatibility. - * See the const char* version for detailed and up-to-date docs. - * @see IsExtensionSupported(const char*) */ - inline bool IsExtensionSupported(const std::string& szExtension) const; - - // ------------------------------------------------------------------- - /** Get a full list of all file extensions supported by ASSIMP. - * - * If a file extension is contained in the list this does of course not - * mean that ASSIMP is able to load all files with this extension --- - * it simply means there is an importer loaded which claims to handle - * files with this file extension. - * @param szOut String to receive the extension list. - * Format of the list: "*.3ds;*.obj;*.dae". This is useful for - * use with the WinAPI call GetOpenFileName(Ex). */ - void GetExtensionList(aiString& szOut) const; - - // ------------------------------------------------------------------- - /** @brief Get a full list of all file extensions supported by ASSIMP. - * - * This function is provided for backward compatibility. - * See the aiString version for detailed and up-to-date docs. - * @see GetExtensionList(aiString&)*/ - inline void GetExtensionList(std::string& szOut) const; - - // ------------------------------------------------------------------- - /** Get the number of importers currently registered with Assimp. */ - size_t GetImporterCount() const; - - // ------------------------------------------------------------------- - /** Get meta data for the importer corresponding to a specific index.. - * - * For the declaration of #aiImporterDesc, include <assimp/importerdesc.h>. - * @param index Index to query, must be within [0,GetImporterCount()) - * @return Importer meta data structure, NULL if the index does not - * exist or if the importer doesn't offer meta information ( - * importers may do this at the cost of being hated by their peers).*/ - const aiImporterDesc* GetImporterInfo(size_t index) const; - - // ------------------------------------------------------------------- - /** Find the importer corresponding to a specific index. - * - * @param index Index to query, must be within [0,GetImporterCount()) - * @return Importer instance. NULL if the index does not - * exist. */ - BaseImporter* GetImporter(size_t index) const; - - // ------------------------------------------------------------------- - /** Find the importer corresponding to a specific file extension. - * - * This is quite similar to #IsExtensionSupported except a - * BaseImporter instance is returned. - * @param szExtension Extension to check for. The following formats - * are recognized (BAH being the file extension): "BAH" (comparison - * is case-insensitive), ".bah", "*.bah" (wild card and dot - * characters at the beginning of the extension are skipped). - * @return NULL if no importer is found*/ - BaseImporter* GetImporter (const char* szExtension) const; - - // ------------------------------------------------------------------- - /** Find the importer index corresponding to a specific file extension. - * - * @param szExtension Extension to check for. The following formats - * are recognized (BAH being the file extension): "BAH" (comparison - * is case-insensitive), ".bah", "*.bah" (wild card and dot - * characters at the beginning of the extension are skipped). - * @return (size_t)-1 if no importer is found */ - size_t GetImporterIndex (const char* szExtension) const; - - // ------------------------------------------------------------------- - /** Returns the storage allocated by ASSIMP to hold the scene data - * in memory. - * - * This refers to the currently loaded file, see #ReadFile(). - * @param in Data structure to be filled. - * @note The returned memory statistics refer to the actual - * size of the use data of the aiScene. Heap-related overhead - * is (naturally) not included.*/ - void GetMemoryRequirements(aiMemoryInfo& in) const; - - // ------------------------------------------------------------------- - /** Enables "extra verbose" mode. - * - * 'Extra verbose' means the data structure is validated after *every* - * single post processing step to make sure everyone modifies the data - * structure in a well-defined manner. This is a debug feature and not - * intended for use in production environments. */ - void SetExtraVerbose(bool bDo); - - // ------------------------------------------------------------------- - /** Private, do not use. */ - ImporterPimpl* Pimpl() { return pimpl; } - const ImporterPimpl* Pimpl() const { return pimpl; } - -protected: - - // Just because we don't want you to know how we're hacking around. - ImporterPimpl* pimpl; -}; //! class Importer - - -// ---------------------------------------------------------------------------- -// For compatibility, the interface of some functions taking a std::string was -// changed to const char* to avoid crashes between binary incompatible STL -// versions. This code her is inlined, so it shouldn't cause any problems. -// ---------------------------------------------------------------------------- - -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE const aiScene* Importer::ReadFile( const std::string& pFile,unsigned int pFlags){ - return ReadFile(pFile.c_str(),pFlags); -} -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE void Importer::GetExtensionList(std::string& szOut) const { - aiString s; - GetExtensionList(s); - szOut = s.data; -} -// ---------------------------------------------------------------------------- -AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string& szExtension) const { - return IsExtensionSupported(szExtension.c_str()); -} - -} // !namespace Assimp - -#endif // AI_ASSIMP_HPP_INC diff --git a/thirdparty/assimp/include/assimp/LineSplitter.h b/thirdparty/assimp/include/assimp/LineSplitter.h deleted file mode 100644 index 6c1097bb6d..0000000000 --- a/thirdparty/assimp/include/assimp/LineSplitter.h +++ /dev/null @@ -1,289 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file LineSplitter.h - * @brief LineSplitter, a helper class to iterate through all lines - * of a file easily. Works with StreamReader. - */ -#pragma once -#ifndef INCLUDED_LINE_SPLITTER_H -#define INCLUDED_LINE_SPLITTER_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <stdexcept> -#include <assimp/StreamReader.h> -#include <assimp/ParsingUtils.h> - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -/** Usage: -@code -for(LineSplitter splitter(stream);splitter;++splitter) { - - if (*splitter == "hi!") { - ... - } - else if (splitter->substr(0,5) == "hello") { - ... - // access the third token in the line (tokens are space-separated) - if (strtol(splitter[2]) > 5) { .. } - } - - std::cout << "Current line is: " << splitter.get_index() << std::endl; -} -@endcode -*/ -// ------------------------------------------------------------------------------------------------ -class LineSplitter { -public: - typedef size_t line_idx; - - // ----------------------------------------- - /** construct from existing stream reader - note: trim is *always* assumed true if skyp_empty_lines==true - */ - LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true); - - ~LineSplitter(); - - // ----------------------------------------- - /** pseudo-iterator increment */ - LineSplitter& operator++(); - - // ----------------------------------------- - LineSplitter& operator++(int); - - // ----------------------------------------- - /** get a pointer to the beginning of a particular token */ - const char* operator[] (size_t idx) const; - - // ----------------------------------------- - /** extract the start positions of N tokens from the current line*/ - template <size_t N> - void get_tokens(const char* (&tokens)[N]) const; - - // ----------------------------------------- - /** member access */ - const std::string* operator -> () const; - - std::string operator* () const; - - // ----------------------------------------- - /** boolean context */ - operator bool() const; - - // ----------------------------------------- - /** line indices are zero-based, empty lines are included */ - operator line_idx() const; - - line_idx get_index() const; - - // ----------------------------------------- - /** access the underlying stream object */ - StreamReaderLE& get_stream(); - - // ----------------------------------------- - /** !strcmp((*this)->substr(0,strlen(check)),check) */ - bool match_start(const char* check); - - // ----------------------------------------- - /** swallow the next call to ++, return the previous value. */ - void swallow_next_increment(); - - LineSplitter( const LineSplitter & ) = delete; - LineSplitter(LineSplitter &&) = delete; - LineSplitter &operator = ( const LineSplitter & ) = delete; - -private: - line_idx mIdx; - std::string mCur; - StreamReaderLE& mStream; - bool mSwallow, mSkip_empty_lines, mTrim; -}; - -AI_FORCE_INLINE -LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) -: mIdx(0) -, mCur() -, mStream(stream) -, mSwallow() -, mSkip_empty_lines(skip_empty_lines) -, mTrim(trim) { - mCur.reserve(1024); - operator++(); - mIdx = 0; -} - -AI_FORCE_INLINE -LineSplitter::~LineSplitter() { - // empty -} - -AI_FORCE_INLINE -LineSplitter& LineSplitter::operator++() { - if (mSwallow) { - mSwallow = false; - return *this; - } - - if (!*this) { - throw std::logic_error("End of file, no more lines to be retrieved."); - } - - char s; - mCur.clear(); - while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) { - if (s == '\n' || s == '\r') { - if (mSkip_empty_lines) { - while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n')); - if (mStream.GetRemainingSize()) { - mStream.IncPtr(-1); - } - } else { - // skip both potential line terminators but don't read past this line. - if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) { - mStream.IncPtr(-1); - } - if (mTrim) { - while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t')); - if (mStream.GetRemainingSize()) { - mStream.IncPtr(-1); - } - } - } - break; - } - mCur += s; - } - ++mIdx; - - return *this; -} - -AI_FORCE_INLINE -LineSplitter &LineSplitter::operator++(int) { - return ++(*this); -} - -AI_FORCE_INLINE -const char *LineSplitter::operator[] (size_t idx) const { - const char* s = operator->()->c_str(); - - SkipSpaces(&s); - for (size_t i = 0; i < idx; ++i) { - - for (; !IsSpace(*s); ++s) { - if (IsLineEnd(*s)) { - throw std::range_error("Token index out of range, EOL reached"); - } - } - SkipSpaces(&s); - } - return s; -} - -template <size_t N> -AI_FORCE_INLINE -void LineSplitter::get_tokens(const char* (&tokens)[N]) const { - const char* s = operator->()->c_str(); - - SkipSpaces(&s); - for (size_t i = 0; i < N; ++i) { - if (IsLineEnd(*s)) { - throw std::range_error("Token count out of range, EOL reached"); - } - tokens[i] = s; - - for (; *s && !IsSpace(*s); ++s); - SkipSpaces(&s); - } -} - -AI_FORCE_INLINE -const std::string* LineSplitter::operator -> () const { - return &mCur; -} - -AI_FORCE_INLINE -std::string LineSplitter::operator* () const { - return mCur; -} - -AI_FORCE_INLINE -LineSplitter::operator bool() const { - return mStream.GetRemainingSize() > 0; -} - -AI_FORCE_INLINE -LineSplitter::operator line_idx() const { - return mIdx; -} - -AI_FORCE_INLINE -LineSplitter::line_idx LineSplitter::get_index() const { - return mIdx; -} - -AI_FORCE_INLINE -StreamReaderLE &LineSplitter::get_stream() { - return mStream; -} - -AI_FORCE_INLINE -bool LineSplitter::match_start(const char* check) { - const size_t len = ::strlen(check); - - return len <= mCur.length() && std::equal(check, check + len, mCur.begin()); -} - -AI_FORCE_INLINE -void LineSplitter::swallow_next_increment() { - mSwallow = true; -} - -} // Namespace Assimp - -#endif // INCLUDED_LINE_SPLITTER_H diff --git a/thirdparty/assimp/include/assimp/LogAux.h b/thirdparty/assimp/include/assimp/LogAux.h deleted file mode 100644 index bcead78dd3..0000000000 --- a/thirdparty/assimp/include/assimp/LogAux.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file LogAux.h - * @brief Common logging usage patterns for importer implementations - */ -#pragma once -#ifndef INCLUDED_AI_LOGAUX_H -#define INCLUDED_AI_LOGAUX_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/TinyFormatter.h> -#include <assimp/Exceptional.h> -#include <assimp/DefaultLogger.hpp> - -namespace Assimp { - -template<class TDeriving> -class LogFunctions { -public: - // ------------------------------------------------------------------------------------------------ - static void ThrowException(const std::string& msg) - { - throw DeadlyImportError(Prefix()+msg); - } - - // ------------------------------------------------------------------------------------------------ - static void LogWarn(const Formatter::format& message) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_WARN(Prefix()+(std::string)message); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogError(const Formatter::format& message) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR(Prefix()+(std::string)message); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogInfo(const Formatter::format& message) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO(Prefix()+(std::string)message); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogDebug(const Formatter::format& message) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_DEBUG(Prefix()+(std::string)message); - } - } - - // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 -#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) - - // ------------------------------------------------------------------------------------------------ - static void LogWarn (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogWarn(Formatter::format(message)); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogError (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogError(Formatter::format(message)); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogInfo (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogInfo(Formatter::format(message)); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogDebug (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogDebug(Formatter::format(message)); - } - } - -#endif - -private: - static const char* Prefix(); - -}; -} // ! Assimp - -#endif diff --git a/thirdparty/assimp/include/assimp/LogStream.hpp b/thirdparty/assimp/include/assimp/LogStream.hpp deleted file mode 100644 index d0281e2d02..0000000000 --- a/thirdparty/assimp/include/assimp/LogStream.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file LogStream.hpp - * @brief Abstract base class 'LogStream', representing an output log stream. - */ -#ifndef INCLUDED_AI_LOGSTREAM_H -#define INCLUDED_AI_LOGSTREAM_H - -#include "types.h" - -namespace Assimp { - -class IOSystem; - -// ------------------------------------------------------------------------------------ -/** @brief CPP-API: Abstract interface for log stream implementations. - * - * Several default implementations are provided, see #aiDefaultLogStream for more - * details. Writing your own implementation of LogStream is just necessary if these - * are not enough for your purpose. */ -class ASSIMP_API LogStream -#ifndef SWIG - : public Intern::AllocateFromAssimpHeap -#endif -{ -protected: - /** @brief Default constructor */ - LogStream() AI_NO_EXCEPT; - -public: - /** @brief Virtual destructor */ - virtual ~LogStream(); - - // ------------------------------------------------------------------- - /** @brief Overwrite this for your own output methods - * - * Log messages *may* consist of multiple lines and you shouldn't - * expect a consistent formatting. If you want custom formatting - * (e.g. generate HTML), supply a custom instance of Logger to - * #DefaultLogger:set(). Usually you can *expect* that a log message - * is exactly one line and terminated with a single \n character. - * @param message Message to be written */ - virtual void write(const char* message) = 0; - - // ------------------------------------------------------------------- - /** @brief Creates a default log stream - * @param streams Type of the default stream - * @param name For aiDefaultLogStream_FILE: name of the output file - * @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output - * file. Pass NULL for the default implementation. - * @return New LogStream instance. */ - static LogStream* createDefaultStream(aiDefaultLogStream stream, - const char* name = "AssimpLog.txt", - IOSystem* io = nullptr ); - -}; // !class LogStream - -inline -LogStream::LogStream() AI_NO_EXCEPT { - // empty -} - -inline -LogStream::~LogStream() { - // empty -} - -// ------------------------------------------------------------------------------------ -} // Namespace Assimp - -#endif diff --git a/thirdparty/assimp/include/assimp/Logger.hpp b/thirdparty/assimp/include/assimp/Logger.hpp deleted file mode 100644 index 89cade6c33..0000000000 --- a/thirdparty/assimp/include/assimp/Logger.hpp +++ /dev/null @@ -1,305 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Logger.hpp - * @brief Abstract base class 'Logger', base of the logging system. - */ -#ifndef INCLUDED_AI_LOGGER_H -#define INCLUDED_AI_LOGGER_H - -#include <assimp/types.h> -#include <assimp/TinyFormatter.h> - -namespace Assimp { - -class LogStream; - -// Maximum length of a log message. Longer messages are rejected. -#define MAX_LOG_MESSAGE_LENGTH 1024u - -// ---------------------------------------------------------------------------------- -/** @brief CPP-API: Abstract interface for logger implementations. - * Assimp provides a default implementation and uses it for almost all - * logging stuff ('DefaultLogger'). This class defines just basic logging - * behavior and is not of interest for you. Instead, take a look at #DefaultLogger. */ -class ASSIMP_API Logger -#ifndef SWIG - : public Intern::AllocateFromAssimpHeap -#endif -{ -public: - - // ---------------------------------------------------------------------- - /** @enum LogSeverity - * @brief Log severity to describe the granularity of logging. - */ - enum LogSeverity { - NORMAL, //!< Normal granularity of logging - VERBOSE //!< Debug infos will be logged, too - }; - - // ---------------------------------------------------------------------- - /** @enum ErrorSeverity - * @brief Description for severity of a log message. - * - * Every LogStream has a bitwise combination of these flags. - * A LogStream doesn't receive any messages of a specific type - * if it doesn't specify the corresponding ErrorSeverity flag. - */ - enum ErrorSeverity { - Debugging = 1, //!< Debug log message - Info = 2, //!< Info log message - Warn = 4, //!< Warn log message - Err = 8 //!< Error log message - }; - -public: - - /** @brief Virtual destructor */ - virtual ~Logger(); - - // ---------------------------------------------------------------------- - /** @brief Writes a debug message - * @param message Debug message*/ - void debug(const char* message); - void debug(const std::string &message); - - // ---------------------------------------------------------------------- - /** @brief Writes a info message - * @param message Info message*/ - void info(const char* message); - void info(const std::string &message); - - // ---------------------------------------------------------------------- - /** @brief Writes a warning message - * @param message Warn message*/ - void warn(const char* message); - void warn(const std::string &message); - - // ---------------------------------------------------------------------- - /** @brief Writes an error message - * @param message Error message*/ - void error(const char* message); - void error(const std::string &message); - - // ---------------------------------------------------------------------- - /** @brief Set a new log severity. - * @param log_severity New severity for logging*/ - void setLogSeverity(LogSeverity log_severity); - - // ---------------------------------------------------------------------- - /** @brief Get the current log severity*/ - LogSeverity getLogSeverity() const; - - // ---------------------------------------------------------------------- - /** @brief Attach a new log-stream - * - * The logger takes ownership of the stream and is responsible - * for its destruction (which is done using ::delete when the logger - * itself is destroyed). Call detachStream to detach a stream and to - * gain ownership of it again. - * @param pStream Log-stream to attach - * @param severity Message filter, specified which types of log - * messages are dispatched to the stream. Provide a bitwise - * combination of the ErrorSeverity flags. - * @return true if the stream has been attached, false otherwise.*/ - virtual bool attachStream(LogStream *pStream, - unsigned int severity = Debugging | Err | Warn | Info) = 0; - - // ---------------------------------------------------------------------- - /** @brief Detach a still attached stream from the logger (or - * modify the filter flags bits) - * @param pStream Log-stream instance for detaching - * @param severity Provide a bitwise combination of the ErrorSeverity - * flags. This value is &~ed with the current flags of the stream, - * if the result is 0 the stream is detached from the Logger and - * the caller retakes the possession of the stream. - * @return true if the stream has been detached, false otherwise.*/ - virtual bool detatchStream(LogStream *pStream, - unsigned int severity = Debugging | Err | Warn | Info) = 0; - -protected: - /** - * Default constructor - */ - Logger() AI_NO_EXCEPT; - - /** - * Construction with a given log severity - */ - explicit Logger(LogSeverity severity); - - // ---------------------------------------------------------------------- - /** - * @brief Called as a request to write a specific debug message - * @param message Debug message. Never longer than - * MAX_LOG_MESSAGE_LENGTH characters (excluding the '0'). - * @note The message string is only valid until the scope of - * the function is left. - */ - virtual void OnDebug(const char* message)= 0; - - // ---------------------------------------------------------------------- - /** - * @brief Called as a request to write a specific info message - * @param message Info message. Never longer than - * MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0'). - * @note The message string is only valid until the scope of - * the function is left. - */ - virtual void OnInfo(const char* message) = 0; - - // ---------------------------------------------------------------------- - /** - * @brief Called as a request to write a specific warn message - * @param message Warn message. Never longer than - * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). - * @note The message string is only valid until the scope of - * the function is left. - */ - virtual void OnWarn(const char* essage) = 0; - - // ---------------------------------------------------------------------- - /** - * @brief Called as a request to write a specific error message - * @param message Error message. Never longer than - * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). - * @note The message string is only valid until the scope of - * the function is left. - */ - virtual void OnError(const char* message) = 0; - -protected: - LogSeverity m_Severity; -}; - -// ---------------------------------------------------------------------------------- -// Default constructor -inline -Logger::Logger() AI_NO_EXCEPT -: m_Severity(NORMAL) { - // empty -} - -// ---------------------------------------------------------------------------------- -// Virtual destructor -inline -Logger::~Logger() { - // empty -} - -// ---------------------------------------------------------------------------------- -// Construction with given logging severity -inline -Logger::Logger(LogSeverity severity) -: m_Severity(severity) { - // empty -} - -// ---------------------------------------------------------------------------------- -// Log severity setter -inline -void Logger::setLogSeverity(LogSeverity log_severity){ - m_Severity = log_severity; -} - -// ---------------------------------------------------------------------------------- -// Log severity getter -inline -Logger::LogSeverity Logger::getLogSeverity() const { - return m_Severity; -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::debug(const std::string &message) { - return debug(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::error(const std::string &message) { - return error(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::warn(const std::string &message) { - return warn(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::info(const std::string &message) { - return info(message.c_str()); -} - -// ------------------------------------------------------------------------------------------------ -#define ASSIMP_LOG_WARN_F(string,...)\ - DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__)) - -#define ASSIMP_LOG_ERROR_F(string,...)\ - DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__)) - -#define ASSIMP_LOG_DEBUG_F(string,...)\ - DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__)) - -#define ASSIMP_LOG_INFO_F(string,...)\ - DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__)) - - -#define ASSIMP_LOG_WARN(string)\ - DefaultLogger::get()->warn(string) - -#define ASSIMP_LOG_ERROR(string)\ - DefaultLogger::get()->error(string) - -#define ASSIMP_LOG_DEBUG(string)\ - DefaultLogger::get()->debug(string) - -#define ASSIMP_LOG_INFO(string)\ - DefaultLogger::get()->info(string) - - -} // Namespace Assimp - -#endif // !! INCLUDED_AI_LOGGER_H diff --git a/thirdparty/assimp/include/assimp/MathFunctions.h b/thirdparty/assimp/include/assimp/MathFunctions.h deleted file mode 100644 index b6c5872a72..0000000000 --- a/thirdparty/assimp/include/assimp/MathFunctions.h +++ /dev/null @@ -1,90 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2016, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -#pragma once - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -/** @file MathFunctions.h -* @brief Implementation of math utility functions. - * -*/ - -#include <limits> - -namespace Assimp { -namespace Math { - -// TODO: use binary GCD for unsigned integers .... -template < typename IntegerType > -inline -IntegerType gcd( IntegerType a, IntegerType b ) { - const IntegerType zero = (IntegerType)0; - while ( true ) { - if ( a == zero ) - return b; - b %= a; - - if ( b == zero ) - return a; - a %= b; - } -} - -template < typename IntegerType > -inline -IntegerType lcm( IntegerType a, IntegerType b ) { - const IntegerType t = gcd (a,b); - if (!t) - return t; - return a / t * b; -} - -template<class T> -inline -T getEpsilon() { - return std::numeric_limits<T>::epsilon(); -} - -} -} diff --git a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h b/thirdparty/assimp/include/assimp/MemoryIOWrapper.h deleted file mode 100644 index 5598d4fc5f..0000000000 --- a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file MemoryIOWrapper.h - * Handy IOStream/IOSystem implemetation to read directly from a memory buffer */ -#pragma once -#ifndef AI_MEMORYIOSTREAM_H_INC -#define AI_MEMORYIOSTREAM_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/IOStream.hpp> -#include <assimp/IOSystem.hpp> -#include <assimp/ai_assert.h> - -#include <stdint.h> - -namespace Assimp { - -#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$" -#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17 - -// ---------------------------------------------------------------------------------- -/** Implementation of IOStream to read directly from a memory buffer */ -// ---------------------------------------------------------------------------------- -class MemoryIOStream : public IOStream { -public: - MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) - : buffer (buff) - , length(len) - , pos((size_t)0) - , own(own) { - // empty - } - - ~MemoryIOStream () { - if(own) { - delete[] buffer; - } - } - - // ------------------------------------------------------------------- - // Read from stream - size_t Read(void* pvBuffer, size_t pSize, size_t pCount) { - ai_assert(nullptr != pvBuffer); - ai_assert(0 != pSize); - - const size_t cnt = std::min( pCount, (length-pos) / pSize); - const size_t ofs = pSize * cnt; - - ::memcpy(pvBuffer,buffer+pos,ofs); - pos += ofs; - - return cnt; - } - - // ------------------------------------------------------------------- - // Write to stream - size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/) { - ai_assert(false); // won't be needed - return 0; - } - - // ------------------------------------------------------------------- - // Seek specific position - aiReturn Seek(size_t pOffset, aiOrigin pOrigin) { - if (aiOrigin_SET == pOrigin) { - if (pOffset > length) { - return AI_FAILURE; - } - pos = pOffset; - } else if (aiOrigin_END == pOrigin) { - if (pOffset > length) { - return AI_FAILURE; - } - pos = length-pOffset; - } else { - if (pOffset+pos > length) { - return AI_FAILURE; - } - pos += pOffset; - } - return AI_SUCCESS; - } - - // ------------------------------------------------------------------- - // Get current seek position - size_t Tell() const { - return pos; - } - - // ------------------------------------------------------------------- - // Get size of file - size_t FileSize() const { - return length; - } - - // ------------------------------------------------------------------- - // Flush file contents - void Flush() { - ai_assert(false); // won't be needed - } - -private: - const uint8_t* buffer; - size_t length,pos; - bool own; -}; - -// --------------------------------------------------------------------------- -/** Dummy IO system to read from a memory buffer */ -class MemoryIOSystem : public IOSystem { -public: - /** Constructor. */ - MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io) - : buffer(buff) - , length(len) - , existing_io(io) - , created_streams() { - // empty - } - - /** Destructor. */ - ~MemoryIOSystem() { - } - - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ - bool Exists(const char* pFile) const override { - if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) { - return true; - } - return existing_io ? existing_io->Exists(pFile) : false; - } - - // ------------------------------------------------------------------- - /** Returns the directory separator. */ - char getOsSeparator() const override { - return existing_io ? existing_io->getOsSeparator() - : '/'; // why not? it doesn't care - } - - // ------------------------------------------------------------------- - /** Open a new file with a given path. */ - IOStream* Open(const char* pFile, const char* pMode = "rb") override { - if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) { - created_streams.emplace_back(new MemoryIOStream(buffer, length)); - return created_streams.back(); - } - return existing_io ? existing_io->Open(pFile, pMode) : NULL; - } - - // ------------------------------------------------------------------- - /** Closes the given file and releases all resources associated with it. */ - void Close( IOStream* pFile) override { - auto it = std::find(created_streams.begin(), created_streams.end(), pFile); - if (it != created_streams.end()) { - delete pFile; - created_streams.erase(it); - } else if (existing_io) { - existing_io->Close(pFile); - } - } - - // ------------------------------------------------------------------- - /** Compare two paths */ - bool ComparePaths(const char* one, const char* second) const override { - return existing_io ? existing_io->ComparePaths(one, second) : false; - } - - bool PushDirectory( const std::string &path ) override { - return existing_io ? existing_io->PushDirectory(path) : false; - } - - const std::string &CurrentDirectory() const override { - static std::string empty; - return existing_io ? existing_io->CurrentDirectory() : empty; - } - - size_t StackSize() const override { - return existing_io ? existing_io->StackSize() : 0; - } - - bool PopDirectory() override { - return existing_io ? existing_io->PopDirectory() : false; - } - - bool CreateDirectory( const std::string &path ) override { - return existing_io ? existing_io->CreateDirectory(path) : false; - } - - bool ChangeDirectory( const std::string &path ) override { - return existing_io ? existing_io->ChangeDirectory(path) : false; - } - - bool DeleteFile( const std::string &file ) override { - return existing_io ? existing_io->DeleteFile(file) : false; - } - -private: - const uint8_t* buffer; - size_t length; - IOSystem* existing_io; - std::vector<IOStream*> created_streams; -}; - -} // end namespace Assimp - -#endif diff --git a/thirdparty/assimp/include/assimp/NullLogger.hpp b/thirdparty/assimp/include/assimp/NullLogger.hpp deleted file mode 100644 index c45d01bd48..0000000000 --- a/thirdparty/assimp/include/assimp/NullLogger.hpp +++ /dev/null @@ -1,99 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file NullLogger.hpp - * @brief Dummy logger -*/ - -#ifndef INCLUDED_AI_NULLLOGGER_H -#define INCLUDED_AI_NULLLOGGER_H - -#include "Logger.hpp" - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** @brief CPP-API: Empty logging implementation. - * - * Does nothing! Used by default if the application hasn't requested a - * custom logger via #DefaultLogger::set() or #DefaultLogger::create(); */ -class ASSIMP_API NullLogger - : public Logger { - -public: - - /** @brief Logs a debug message */ - void OnDebug(const char* message) { - (void)message; //this avoids compiler warnings - } - - /** @brief Logs an info message */ - void OnInfo(const char* message) { - (void)message; //this avoids compiler warnings - } - - /** @brief Logs a warning message */ - void OnWarn(const char* message) { - (void)message; //this avoids compiler warnings - } - - /** @brief Logs an error message */ - void OnError(const char* message) { - (void)message; //this avoids compiler warnings - } - - /** @brief Detach a still attached stream from logger */ - bool attachStream(LogStream *pStream, unsigned int severity) { - (void)pStream; (void)severity; //this avoids compiler warnings - return false; - } - - /** @brief Detach a still attached stream from logger */ - bool detatchStream(LogStream *pStream, unsigned int severity) { - (void)pStream; (void)severity; //this avoids compiler warnings - return false; - } - -private: -}; -} -#endif // !! AI_NULLLOGGER_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/ParsingUtils.h b/thirdparty/assimp/include/assimp/ParsingUtils.h deleted file mode 100644 index 3025601246..0000000000 --- a/thirdparty/assimp/include/assimp/ParsingUtils.h +++ /dev/null @@ -1,264 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - - -/** @file ParsingUtils.h - * @brief Defines helper functions for text parsing - */ -#pragma once -#ifndef AI_PARSING_UTILS_H_INC -#define AI_PARSING_UTILS_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/StringComparison.h> -#include <assimp/StringUtils.h> -#include <assimp/defs.h> - -namespace Assimp { - -// NOTE: the functions below are mostly intended as replacement for -// std::upper, std::lower, std::isupper, std::islower, std::isspace. -// we don't bother of locales. We don't want them. We want reliable -// (i.e. identical) results across all locales. - -// The functions below accept any character type, but know only -// about ASCII. However, UTF-32 is the only safe ASCII superset to -// use since it doesn't have multi-byte sequences. - -static const unsigned int BufferSize = 4096; - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -char_t ToLower( char_t in ) { - return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -char_t ToUpper( char_t in) { - return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in; -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool IsUpper( char_t in) { - return (in >= (char_t)'A' && in <= (char_t)'Z'); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool IsLower( char_t in) { - return (in >= (char_t)'a' && in <= (char_t)'z'); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool IsSpace( char_t in) { - return (in == (char_t)' ' || in == (char_t)'\t'); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool IsLineEnd( char_t in) { - return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool IsSpaceOrNewLine( char_t in) { - return IsSpace<char_t>(in) || IsLineEnd<char_t>(in); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool SkipSpaces( const char_t* in, const char_t** out) { - while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) { - ++in; - } - *out = in; - return !IsLineEnd<char_t>(*in); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool SkipSpaces( const char_t** inout) { - return SkipSpaces<char_t>(*inout,inout); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool SkipLine( const char_t* in, const char_t** out) { - while( *in != ( char_t )'\r' && *in != ( char_t )'\n' && *in != ( char_t )'\0' ) { - ++in; - } - - // files are opened in binary mode. Ergo there are both NL and CR - while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { - ++in; - } - *out = in; - return *in != (char_t)'\0'; -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool SkipLine( const char_t** inout) { - return SkipLine<char_t>(*inout,inout); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) { - while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { - ++in; - } - *out = in; - return *in != '\0'; -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool SkipSpacesAndLineEnd( const char_t** inout) { - return SkipSpacesAndLineEnd<char_t>(*inout,inout); -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) { - if( ( char_t )'\0' == *buffer ) { - return false; - } - - char* _out = out; - char* const end = _out + BufferSize; - while( !IsLineEnd( *buffer ) && _out < end ) { - *_out++ = *buffer++; - } - *_out = (char_t)'\0'; - - while( IsLineEnd( *buffer ) && '\0' != *buffer ) { - ++buffer; - } - - return true; -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE bool IsNumeric( char_t in) { - return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; -} - -// --------------------------------------------------------------------------------- -template <class char_t> -AI_FORCE_INLINE -bool TokenMatch(char_t*& in, const char* token, unsigned int len) -{ - if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - if (in[len] != '\0') { - in += len+1; - } else { - // If EOF after the token make sure we don't go past end of buffer - in += len; - } - return true; - } - - return false; -} -// --------------------------------------------------------------------------------- -/** @brief Case-ignoring version of TokenMatch - * @param in Input - * @param token Token to check for - * @param len Number of characters to check - */ -AI_FORCE_INLINE -bool TokenMatchI(const char*& in, const char* token, unsigned int len) { - if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - in += len+1; - return true; - } - return false; -} - -// --------------------------------------------------------------------------------- -AI_FORCE_INLINE -void SkipToken(const char*& in) { - SkipSpaces(&in); - while ( !IsSpaceOrNewLine( *in ) ) { - ++in; - } -} - -// --------------------------------------------------------------------------------- -AI_FORCE_INLINE -std::string GetNextToken(const char*& in) { - SkipSpacesAndLineEnd(&in); - const char* cur = in; - while ( !IsSpaceOrNewLine( *in ) ) { - ++in; - } - return std::string(cur,(size_t)(in-cur)); -} - -// --------------------------------------------------------------------------------- - -} // ! namespace Assimp - -#endif // ! AI_PARSING_UTILS_H_INC diff --git a/thirdparty/assimp/include/assimp/Profiler.h b/thirdparty/assimp/include/assimp/Profiler.h deleted file mode 100644 index 624029be99..0000000000 --- a/thirdparty/assimp/include/assimp/Profiler.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Profiler.h - * @brief Utility to measure the respective runtime of each import step - */ -#pragma once -#ifndef AI_INCLUDED_PROFILER_H -#define AI_INCLUDED_PROFILER_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <chrono> -#include <assimp/DefaultLogger.hpp> -#include <assimp/TinyFormatter.h> - -#include <map> - -namespace Assimp { -namespace Profiling { - -using namespace Formatter; - -// ------------------------------------------------------------------------------------------------ -/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically - * dumped to the log file. - */ -class Profiler { -public: - Profiler() { - // empty - } - - - /** Start a named timer */ - void BeginRegion(const std::string& region) { - regions[region] = std::chrono::system_clock::now(); - ASSIMP_LOG_DEBUG((format("START `"),region,"`")); - } - - - /** End a specific named timer and write its end time to the log */ - void EndRegion(const std::string& region) { - RegionMap::const_iterator it = regions.find(region); - if (it == regions.end()) { - return; - } - - std::chrono::duration<double> elapsedSeconds = std::chrono::system_clock::now() - regions[region]; - ASSIMP_LOG_DEBUG((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s")); - } - -private: - typedef std::map<std::string,std::chrono::time_point<std::chrono::system_clock>> RegionMap; - RegionMap regions; -}; - -} -} - -#endif // AI_INCLUDED_PROFILER_H - diff --git a/thirdparty/assimp/include/assimp/ProgressHandler.hpp b/thirdparty/assimp/include/assimp/ProgressHandler.hpp deleted file mode 100644 index 8991a64618..0000000000 --- a/thirdparty/assimp/include/assimp/ProgressHandler.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file ProgressHandler.hpp - * @brief Abstract base class 'ProgressHandler'. - */ -#pragma once -#ifndef AI_PROGRESSHANDLER_H_INC -#define AI_PROGRESSHANDLER_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -namespace Assimp { - -// ------------------------------------------------------------------------------------ -/** @brief CPP-API: Abstract interface for custom progress report receivers. - * - * Each #Importer instance maintains its own #ProgressHandler. The default - * implementation provided by Assimp doesn't do anything at all. */ -class ASSIMP_API ProgressHandler -#ifndef SWIG - : public Intern::AllocateFromAssimpHeap -#endif -{ -protected: - /// @brief Default constructor - ProgressHandler () AI_NO_EXCEPT { - // empty - } - -public: - /// @brief Virtual destructor. - virtual ~ProgressHandler () { - } - - // ------------------------------------------------------------------- - /** @brief Progress callback. - * @param percentage An estimate of the current loading progress, - * in percent. Or -1.f if such an estimate is not available. - * - * There are restriction on what you may do from within your - * implementation of this method: no exceptions may be thrown and no - * non-const #Importer methods may be called. It is - * not generally possible to predict the number of callbacks - * fired during a single import. - * - * @return Return false to abort loading at the next possible - * occasion (loaders and Assimp are generally allowed to perform - * all needed cleanup tasks prior to returning control to the - * caller). If the loading is aborted, #Importer::ReadFile() - * returns always NULL. - * */ - virtual bool Update(float percentage = -1.f) = 0; - - // ------------------------------------------------------------------- - /** @brief Progress callback for file loading steps - * @param numberOfSteps The number of total post-processing - * steps - * @param currentStep The index of the current post-processing - * step that will run, or equal to numberOfSteps if all of - * them has finished. This number is always strictly monotone - * increasing, although not necessarily linearly. - * - * @note This is currently only used at the start and the end - * of the file parsing. - * */ - virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; - Update( f * 0.5f ); - } - - // ------------------------------------------------------------------- - /** @brief Progress callback for post-processing steps - * @param numberOfSteps The number of total post-processing - * steps - * @param currentStep The index of the current post-processing - * step that will run, or equal to numberOfSteps if all of - * them has finished. This number is always strictly monotone - * increasing, although not necessarily linearly. - * */ - virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; - Update( f * 0.5f + 0.5f ); - } - - - // ------------------------------------------------------------------- - /** @brief Progress callback for export steps. - * @param numberOfSteps The number of total processing - * steps - * @param currentStep The index of the current post-processing - * step that will run, or equal to numberOfSteps if all of - * them has finished. This number is always strictly monotone - * increasing, although not necessarily linearly. - * */ - virtual void UpdateFileWrite(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; - Update(f * 0.5f); - } -}; // !class ProgressHandler - -// ------------------------------------------------------------------------------------ - -} // Namespace Assimp - -#endif // AI_PROGRESSHANDLER_H_INC diff --git a/thirdparty/assimp/include/assimp/RemoveComments.h b/thirdparty/assimp/include/assimp/RemoveComments.h deleted file mode 100644 index f129420535..0000000000 --- a/thirdparty/assimp/include/assimp/RemoveComments.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Declares a helper class, "CommentRemover", which can be - * used to remove comments (single and multi line) from a text file. - */ -#pragma once -#ifndef AI_REMOVE_COMMENTS_H_INC -#define AI_REMOVE_COMMENTS_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/defs.h> - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** \brief Helper class to remove single and multi line comments from a file - * - * Some mesh formats like MD5 have comments that are quite similar - * to those in C or C++ so this code has been moved to a separate - * module. - */ -class ASSIMP_API CommentRemover { - // class cannot be instanced - CommentRemover() {} - -public: - - //! Remove single-line comments. The end of a line is - //! expected to be either NL or CR or NLCR. - //! \param szComment The start sequence of the comment, e.g. "//" - //! \param szBuffer Buffer to work with - //! \param chReplacement Character to be used as replacement - //! for commented lines. By default this is ' ' - static void RemoveLineComments(const char* szComment, - char* szBuffer, char chReplacement = ' '); - - //! Remove multi-line comments. The end of a line is - //! expected to be either NL or CR or NLCR. Multi-line comments - //! may not be nested (as in C). - //! \param szCommentStart The start sequence of the comment, e.g. "/*" - //! \param szCommentEnd The end sequence of the comment, e.g. "*/" - //! \param szBuffer Buffer to work with - //! \param chReplacement Character to be used as replacement - //! for commented lines. By default this is ' ' - static void RemoveMultiLineComments(const char* szCommentStart, - const char* szCommentEnd,char* szBuffer, - char chReplacement = ' '); -}; -} // ! Assimp - -#endif // !! AI_REMOVE_COMMENTS_H_INC diff --git a/thirdparty/assimp/include/assimp/SGSpatialSort.h b/thirdparty/assimp/include/assimp/SGSpatialSort.h deleted file mode 100644 index fdb5ce8174..0000000000 --- a/thirdparty/assimp/include/assimp/SGSpatialSort.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** Small helper classes to optimize finding vertices close to a given location - */ -#pragma once -#ifndef AI_D3DSSPATIALSORT_H_INC -#define AI_D3DSSPATIALSORT_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> -#include <vector> -#include <stdint.h> - -namespace Assimp { - -// ---------------------------------------------------------------------------------- -/** Specialized version of SpatialSort to support smoothing groups - * This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their - * normal computation code in SmoothingGroups.inl, the LWO loader has its own - * implementation to handle all details of its file format correctly. - */ -// ---------------------------------------------------------------------------------- -class ASSIMP_API SGSpatialSort -{ -public: - - SGSpatialSort(); - - // ------------------------------------------------------------------- - /** Construction from a given face array, handling smoothing groups - * properly - */ - explicit SGSpatialSort(const std::vector<aiVector3D>& vPositions); - - // ------------------------------------------------------------------- - /** Add a vertex to the spatial sort - * @param vPosition Vertex position to be added - * @param index Index of the vrtex - * @param smoothingGroup SmoothingGroup for this vertex - */ - void Add(const aiVector3D& vPosition, unsigned int index, - unsigned int smoothingGroup); - - // ------------------------------------------------------------------- - /** Prepare the spatial sorter for use. This step runs in O(logn) - */ - void Prepare(); - - /** Destructor */ - ~SGSpatialSort(); - - // ------------------------------------------------------------------- - /** Returns an iterator for all positions close to the given position. - * @param pPosition The position to look for vertices. - * @param pSG Only included vertices with at least one shared smooth group - * @param pRadius Maximal distance from the position a vertex may have - * to be counted in. - * @param poResults The container to store the indices of the found - * positions. Will be emptied by the call so it may contain anything. - * @param exactMatch Specifies whether smoothing groups are bit masks - * (false) or integral values (true). In the latter case, a vertex - * cannot belong to more than one smoothing group. - * @return An iterator to iterate over all vertices in the given area. - */ - // ------------------------------------------------------------------- - void FindPositions( const aiVector3D& pPosition, uint32_t pSG, - float pRadius, std::vector<unsigned int>& poResults, - bool exactMatch = false) const; - -protected: - /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */ - aiVector3D mPlaneNormal; - - // ------------------------------------------------------------------- - /** An entry in a spatially sorted position array. Consists of a - * vertex index, its position and its pre-calculated distance from - * the reference plane */ - // ------------------------------------------------------------------- - struct Entry { - unsigned int mIndex; ///< The vertex referred by this entry - aiVector3D mPosition; ///< Position - uint32_t mSmoothGroups; - float mDistance; ///< Distance of this vertex to the sorting plane - - Entry() AI_NO_EXCEPT - : mIndex(0) - , mPosition() - , mSmoothGroups(0) - , mDistance(0.0f) { - // empty - } - - Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG) - : mIndex( pIndex) - , mPosition( pPosition) - , mSmoothGroups(pSG) - , mDistance( pDistance) { - // empty - } - - bool operator < (const Entry& e) const { - return mDistance < e.mDistance; - } - }; - - // all positions, sorted by distance to the sorting plane - std::vector<Entry> mPositions; -}; - -} // end of namespace Assimp - -#endif // AI_SPATIALSORT_H_INC diff --git a/thirdparty/assimp/include/assimp/SceneCombiner.h b/thirdparty/assimp/include/assimp/SceneCombiner.h deleted file mode 100644 index 0683c1e052..0000000000 --- a/thirdparty/assimp/include/assimp/SceneCombiner.h +++ /dev/null @@ -1,410 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Declares a helper class, "SceneCombiner" providing various - * utilities to merge scenes. - */ -#pragma once -#ifndef AI_SCENE_COMBINER_H_INC -#define AI_SCENE_COMBINER_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/ai_assert.h> -#include <assimp/types.h> -#include <assimp/Defines.h> - -#include <stddef.h> -#include <set> -#include <list> -#include <stdint.h> -#include <vector> - -struct aiScene; -struct aiNode; -struct aiMaterial; -struct aiTexture; -struct aiCamera; -struct aiLight; -struct aiMetadata; -struct aiBone; -struct aiMesh; -struct aiAnimMesh; -struct aiAnimation; -struct aiNodeAnim; -struct aiMeshMorphAnim; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** \brief Helper data structure for SceneCombiner. - * - * Describes to which node a scene must be attached to. - */ -struct AttachmentInfo -{ - AttachmentInfo() - : scene (NULL) - , attachToNode (NULL) - {} - - AttachmentInfo(aiScene* _scene, aiNode* _attachToNode) - : scene (_scene) - , attachToNode (_attachToNode) - {} - - aiScene* scene; - aiNode* attachToNode; -}; - -// --------------------------------------------------------------------------- -struct NodeAttachmentInfo -{ - NodeAttachmentInfo() - : node (NULL) - , attachToNode (NULL) - , resolved (false) - , src_idx (SIZE_MAX) - {} - - NodeAttachmentInfo(aiNode* _scene, aiNode* _attachToNode,size_t idx) - : node (_scene) - , attachToNode (_attachToNode) - , resolved (false) - , src_idx (idx) - {} - - aiNode* node; - aiNode* attachToNode; - bool resolved; - size_t src_idx; -}; - -// --------------------------------------------------------------------------- -/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES - * Generate unique names for all named scene items - */ -#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1 - -/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES - * Generate unique names for materials, too. - * This is not absolutely required to pass the validation. - */ -#define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2 - -/** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY - * Use deep copies of duplicate scenes - */ -#define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4 - -/** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS - * If attachment nodes are not found in the given master scene, - * search the other imported scenes for them in an any order. - */ -#define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8 - -/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY - * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES. - * Unique names are generated, but only if this is absolutely - * required to avoid name conflicts. - */ -#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10 - -typedef std::pair<aiBone*,unsigned int> BoneSrcIndex; - -// --------------------------------------------------------------------------- -/** @brief Helper data structure for SceneCombiner::MergeBones. - */ -struct BoneWithHash : public std::pair<uint32_t,aiString*> { - std::vector<BoneSrcIndex> pSrcBones; -}; - -// --------------------------------------------------------------------------- -/** @brief Utility for SceneCombiner - */ -struct SceneHelper -{ - SceneHelper () - : scene (NULL) - , idlen (0) - { - id[0] = 0; - } - - explicit SceneHelper (aiScene* _scene) - : scene (_scene) - , idlen (0) - { - id[0] = 0; - } - - AI_FORCE_INLINE aiScene* operator-> () const - { - return scene; - } - - // scene we're working on - aiScene* scene; - - // prefix to be added to all identifiers in the scene ... - char id [32]; - - // and its strlen() - unsigned int idlen; - - // hash table to quickly check whether a name is contained in the scene - std::set<unsigned int> hashes; -}; - -// --------------------------------------------------------------------------- -/** \brief Static helper class providing various utilities to merge two - * scenes. It is intended as internal utility and NOT for use by - * applications. - * - * The class is currently being used by various postprocessing steps - * and loaders (ie. LWS). - */ -class ASSIMP_API SceneCombiner { - // class cannot be instanced - SceneCombiner() { - // empty - } - - ~SceneCombiner() { - // empty - } - -public: - // ------------------------------------------------------------------- - /** Merges two or more scenes. - * - * @param dest Receives a pointer to the destination scene. If the - * pointer doesn't point to NULL when the function is called, the - * existing scene is cleared and refilled. - * @param src Non-empty list of scenes to be merged. The function - * deletes the input scenes afterwards. There may be duplicate scenes. - * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above - */ - static void MergeScenes(aiScene** dest,std::vector<aiScene*>& src, - unsigned int flags = 0); - - // ------------------------------------------------------------------- - /** Merges two or more scenes and attaches all scenes to a specific - * position in the node graph of the master scene. - * - * @param dest Receives a pointer to the destination scene. If the - * pointer doesn't point to NULL when the function is called, the - * existing scene is cleared and refilled. - * @param master Master scene. It will be deleted afterwards. All - * other scenes will be inserted in its node graph. - * @param src Non-empty list of scenes to be merged along with their - * corresponding attachment points in the master scene. The function - * deletes the input scenes afterwards. There may be duplicate scenes. - * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above - */ - static void MergeScenes(aiScene** dest, aiScene* master, - std::vector<AttachmentInfo>& src, - unsigned int flags = 0); - - // ------------------------------------------------------------------- - /** Merges two or more meshes - * - * The meshes should have equal vertex formats. Only components - * that are provided by ALL meshes will be present in the output mesh. - * An exception is made for VColors - they are set to black. The - * meshes should have the same material indices, too. The output - * material index is always the material index of the first mesh. - * - * @param dest Destination mesh. Must be empty. - * @param flags Currently no parameters - * @param begin First mesh to be processed - * @param end Points to the mesh after the last mesh to be processed - */ - static void MergeMeshes(aiMesh** dest,unsigned int flags, - std::vector<aiMesh*>::const_iterator begin, - std::vector<aiMesh*>::const_iterator end); - - // ------------------------------------------------------------------- - /** Merges two or more bones - * - * @param out Mesh to receive the output bone list - * @param flags Currently no parameters - * @param begin First mesh to be processed - * @param end Points to the mesh after the last mesh to be processed - */ - static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it, - std::vector<aiMesh*>::const_iterator end); - - // ------------------------------------------------------------------- - /** Merges two or more materials - * - * The materials should be complementary as much as possible. In case - * of a property present in different materials, the first occurrence - * is used. - * - * @param dest Destination material. Must be empty. - * @param begin First material to be processed - * @param end Points to the material after the last material to be processed - */ - static void MergeMaterials(aiMaterial** dest, - std::vector<aiMaterial*>::const_iterator begin, - std::vector<aiMaterial*>::const_iterator end); - - // ------------------------------------------------------------------- - /** Builds a list of uniquely named bones in a mesh list - * - * @param asBones Receives the output list - * @param it First mesh to be processed - * @param end Last mesh to be processed - */ - static void BuildUniqueBoneList(std::list<BoneWithHash>& asBones, - std::vector<aiMesh*>::const_iterator it, - std::vector<aiMesh*>::const_iterator end); - - // ------------------------------------------------------------------- - /** Add a name prefix to all nodes in a scene. - * - * @param Current node. This function is called recursively. - * @param prefix Prefix to be added to all nodes - * @param len STring length - */ - static void AddNodePrefixes(aiNode* node, const char* prefix, - unsigned int len); - - // ------------------------------------------------------------------- - /** Add an offset to all mesh indices in a node graph - * - * @param Current node. This function is called recursively. - * @param offset Offset to be added to all mesh indices - */ - static void OffsetNodeMeshIndices (aiNode* node, unsigned int offset); - - // ------------------------------------------------------------------- - /** Attach a list of node graphs to well-defined nodes in a master - * graph. This is a helper for MergeScenes() - * - * @param master Master scene - * @param srcList List of source scenes along with their attachment - * points. If an attachment point is NULL (or does not exist in - * the master graph), a scene is attached to the root of the master - * graph (as an additional child node) - * @duplicates List of duplicates. If elem[n] == n the scene is not - * a duplicate. Otherwise elem[n] links scene n to its first occurrence. - */ - static void AttachToGraph ( aiScene* master, - std::vector<NodeAttachmentInfo>& srcList); - - static void AttachToGraph (aiNode* attach, - std::vector<NodeAttachmentInfo>& srcList); - - - // ------------------------------------------------------------------- - /** Get a deep copy of a scene - * - * @param dest Receives a pointer to the destination scene - * @param src Source scene - remains unmodified. - */ - static void CopyScene(aiScene** dest,const aiScene* source,bool allocate = true); - - - // ------------------------------------------------------------------- - /** Get a flat copy of a scene - * - * Only the first hierarchy layer is copied. All pointer members of - * aiScene are shared by source and destination scene. If the - * pointer doesn't point to NULL when the function is called, the - * existing scene is cleared and refilled. - * @param dest Receives a pointer to the destination scene - * @param src Source scene - remains unmodified. - */ - static void CopySceneFlat(aiScene** dest,const aiScene* source); - - - // ------------------------------------------------------------------- - /** Get a deep copy of a mesh - * - * @param dest Receives a pointer to the destination mesh - * @param src Source mesh - remains unmodified. - */ - static void Copy (aiMesh** dest, const aiMesh* src); - - // similar to Copy(): - static void Copy (aiAnimMesh** dest, const aiAnimMesh* src); - static void Copy (aiMaterial** dest, const aiMaterial* src); - static void Copy (aiTexture** dest, const aiTexture* src); - static void Copy (aiAnimation** dest, const aiAnimation* src); - static void Copy (aiCamera** dest, const aiCamera* src); - static void Copy (aiBone** dest, const aiBone* src); - static void Copy (aiLight** dest, const aiLight* src); - static void Copy (aiNodeAnim** dest, const aiNodeAnim* src); - static void Copy (aiMeshMorphAnim** dest, const aiMeshMorphAnim* src); - static void Copy (aiMetadata** dest, const aiMetadata* src); - - // recursive, of course - static void Copy (aiNode** dest, const aiNode* src); - - -private: - - // ------------------------------------------------------------------- - // Same as AddNodePrefixes, but with an additional check - static void AddNodePrefixesChecked(aiNode* node, const char* prefix, - unsigned int len, - std::vector<SceneHelper>& input, - unsigned int cur); - - // ------------------------------------------------------------------- - // Add node identifiers to a hashing set - static void AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes); - - - // ------------------------------------------------------------------- - // Search for duplicate names - static bool FindNameMatch(const aiString& name, - std::vector<SceneHelper>& input, unsigned int cur); -}; - -} - -#endif // !! AI_SCENE_COMBINER_H_INC diff --git a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h deleted file mode 100644 index ad979a33fa..0000000000 --- a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h +++ /dev/null @@ -1,130 +0,0 @@ -/** Helper class to construct a dummy mesh for file formats containing only motion data */ - -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file SkeletonMeshBuilder.h - * Declares SkeletonMeshBuilder, a tiny utility to build dummy meshes - * for animation skeletons. - */ - -#pragma once -#ifndef AI_SKELETONMESHBUILDER_H_INC -#define AI_SKELETONMESHBUILDER_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <vector> -#include <assimp/mesh.h> - -struct aiMaterial; -struct aiScene; -struct aiNode; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** - * This little helper class constructs a dummy mesh for a given scene - * the resembles the node hierarchy. This is useful for file formats - * that don't carry any mesh data but only animation data. - */ -class ASSIMP_API SkeletonMeshBuilder -{ -public: - - // ------------------------------------------------------------------- - /** The constructor processes the given scene and adds a mesh there. - * - * Does nothing if the scene already has mesh data. - * @param pScene The scene for which a skeleton mesh should be constructed. - * @param root The node to start with. NULL is the scene root - * @param bKnobsOnly Set this to true if you don't want the connectors - * between the knobs representing the nodes. - */ - SkeletonMeshBuilder( aiScene* pScene, aiNode* root = NULL, - bool bKnobsOnly = false); - -protected: - - // ------------------------------------------------------------------- - /** Recursively builds a simple mesh representation for the given node - * and also creates a joint for the node that affects this part of - * the mesh. - * @param pNode The node to build geometry for. - */ - void CreateGeometry( const aiNode* pNode); - - // ------------------------------------------------------------------- - /** Creates the mesh from the internally accumulated stuff and returns it. - */ - aiMesh* CreateMesh(); - - // ------------------------------------------------------------------- - /** Creates a dummy material and returns it. */ - aiMaterial* CreateMaterial(); - -protected: - /** space to assemble the mesh data: points */ - std::vector<aiVector3D> mVertices; - - /** faces */ - struct Face - { - unsigned int mIndices[3]; - Face(); - Face( unsigned int p0, unsigned int p1, unsigned int p2) - { mIndices[0] = p0; mIndices[1] = p1; mIndices[2] = p2; } - }; - std::vector<Face> mFaces; - - /** bones */ - std::vector<aiBone*> mBones; - - bool mKnobsOnly; -}; - -} // end of namespace Assimp - -#endif // AI_SKELETONMESHBUILDER_H_INC diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.h b/thirdparty/assimp/include/assimp/SmoothingGroups.h deleted file mode 100644 index c1a93947f1..0000000000 --- a/thirdparty/assimp/include/assimp/SmoothingGroups.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines the helper data structures for importing 3DS files. -http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */ - -#pragma once -#ifndef AI_SMOOTHINGGROUPS_H_INC -#define AI_SMOOTHINGGROUPS_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/vector3.h> - -#include <stdint.h> -#include <vector> - -// --------------------------------------------------------------------------- -/** Helper structure representing a face with smoothing groups assigned */ -struct FaceWithSmoothingGroup { - FaceWithSmoothingGroup() AI_NO_EXCEPT - : mIndices() - , iSmoothGroup(0) { - // in debug builds set all indices to a common magic value -#ifdef ASSIMP_BUILD_DEBUG - this->mIndices[0] = 0xffffffff; - this->mIndices[1] = 0xffffffff; - this->mIndices[2] = 0xffffffff; -#endif - } - - - //! Indices. .3ds is using uint16. However, after - //! an unique vertex set has been generated, - //! individual index values might exceed 2^16 - uint32_t mIndices[3]; - - //! specifies to which smoothing group the face belongs to - uint32_t iSmoothGroup; -}; - -// --------------------------------------------------------------------------- -/** Helper structure representing a mesh whose faces have smoothing - groups assigned. This allows us to reuse the code for normal computations - from smoothings groups for several loaders (3DS, ASE). All of them - use face structures which inherit from #FaceWithSmoothingGroup, - but as they add extra members and need to be copied by value we - need to use a template here. - */ -template <class T> -struct MeshWithSmoothingGroups -{ - //! Vertex positions - std::vector<aiVector3D> mPositions; - - //! Face lists - std::vector<T> mFaces; - - //! List of normal vectors - std::vector<aiVector3D> mNormals; -}; - -// --------------------------------------------------------------------------- -/** Computes normal vectors for the mesh - */ -template <class T> -void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh); - - -// include implementations -#include "SmoothingGroups.inl" - -#endif // !! AI_SMOOTHINGGROUPS_H_INC diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.inl b/thirdparty/assimp/include/assimp/SmoothingGroups.inl deleted file mode 100644 index 37ea083dbe..0000000000 --- a/thirdparty/assimp/include/assimp/SmoothingGroups.inl +++ /dev/null @@ -1,141 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Generation of normal vectors basing on smoothing groups */ - -#pragma once -#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED -#define AI_SMOOTHINGGROUPS_INL_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/SGSpatialSort.h> - -#include <algorithm> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -template <class T> -void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh) -{ - // First generate face normals - sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D()); - for( unsigned int a = 0; a < sMesh.mFaces.size(); a++) - { - T& face = sMesh.mFaces[a]; - - aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]]; - aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]]; - aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]]; - - aiVector3D pDelta1 = *pV2 - *pV1; - aiVector3D pDelta2 = *pV3 - *pV1; - aiVector3D vNor = pDelta1 ^ pDelta2; - - for (unsigned int c = 0; c < 3;++c) - sMesh.mNormals[face.mIndices[c]] = vNor; - } - - // calculate the position bounds so we have a reliable epsilon to check position differences against - aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); - for( unsigned int a = 0; a < sMesh.mPositions.size(); a++) - { - minVec.x = std::min( minVec.x, sMesh.mPositions[a].x); - minVec.y = std::min( minVec.y, sMesh.mPositions[a].y); - minVec.z = std::min( minVec.z, sMesh.mPositions[a].z); - maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x); - maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y); - maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z); - } - const float posEpsilon = (maxVec - minVec).Length() * 1e-5f; - std::vector<aiVector3D> avNormals; - avNormals.resize(sMesh.mNormals.size()); - - // now generate the spatial sort tree - SGSpatialSort sSort; - for( typename std::vector<T>::iterator i = sMesh.mFaces.begin(); - i != sMesh.mFaces.end();++i) - { - for (unsigned int c = 0; c < 3;++c) - sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup); - } - sSort.Prepare(); - - std::vector<bool> vertexDone(sMesh.mPositions.size(),false); - for( typename std::vector<T>::iterator i = sMesh.mFaces.begin(); - i != sMesh.mFaces.end();++i) - { - std::vector<unsigned int> poResult; - for (unsigned int c = 0; c < 3;++c) - { - unsigned int idx = (*i).mIndices[c]; - if (vertexDone[idx])continue; - - sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup, - posEpsilon,poResult); - - aiVector3D vNormals; - for (std::vector<unsigned int>::const_iterator - a = poResult.begin(); - a != poResult.end();++a) - { - vNormals += sMesh.mNormals[(*a)]; - } - vNormals.NormalizeSafe(); - - // write back into all affected normals - for (std::vector<unsigned int>::const_iterator - a = poResult.begin(); - a != poResult.end();++a) - { - idx = *a; - avNormals [idx] = vNormals; - vertexDone[idx] = true; - } - } - } - sMesh.mNormals = avNormals; -} - -#endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED diff --git a/thirdparty/assimp/include/assimp/SpatialSort.h b/thirdparty/assimp/include/assimp/SpatialSort.h deleted file mode 100644 index 9f93543150..0000000000 --- a/thirdparty/assimp/include/assimp/SpatialSort.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** Small helper classes to optimise finding vertizes close to a given location */ -#pragma once -#ifndef AI_SPATIALSORT_H_INC -#define AI_SPATIALSORT_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <vector> -#include <assimp/types.h> - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -/** A little helper class to quickly find all vertices in the epsilon environment of a given - * position. Construct an instance with an array of positions. The class stores the given positions - * by their indices and sorts them by their distance to an arbitrary chosen plane. - * You can then query the instance for all vertices close to a given position in an average O(log n) - * time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen - * so that it avoids common planes in usual data sets. */ -// ------------------------------------------------------------------------------------------------ -class ASSIMP_API SpatialSort -{ -public: - - SpatialSort(); - - // ------------------------------------------------------------------------------------ - /** Constructs a spatially sorted representation from the given position array. - * Supply the positions in its layout in memory, the class will only refer to them - * by index. - * @param pPositions Pointer to the first position vector of the array. - * @param pNumPositions Number of vectors to expect in that array. - * @param pElementOffset Offset in bytes from the beginning of one vector in memory - * to the beginning of the next vector. */ - SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, - unsigned int pElementOffset); - - /** Destructor */ - ~SpatialSort(); - -public: - - // ------------------------------------------------------------------------------------ - /** Sets the input data for the SpatialSort. This replaces existing data, if any. - * The new data receives new indices in ascending order. - * - * @param pPositions Pointer to the first position vector of the array. - * @param pNumPositions Number of vectors to expect in that array. - * @param pElementOffset Offset in bytes from the beginning of one vector in memory - * to the beginning of the next vector. - * @param pFinalize Specifies whether the SpatialSort's internal representation - * is finalized after the new data has been added. Finalization is - * required in order to use #FindPosition() or #GenerateMappingTable(). - * If you don't finalize yet, you can use #Append() to add data from - * other sources.*/ - void Fill( const aiVector3D* pPositions, unsigned int pNumPositions, - unsigned int pElementOffset, - bool pFinalize = true); - - - // ------------------------------------------------------------------------------------ - /** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */ - void Append( const aiVector3D* pPositions, unsigned int pNumPositions, - unsigned int pElementOffset, - bool pFinalize = true); - - - // ------------------------------------------------------------------------------------ - /** Finalize the spatial hash data structure. This can be useful after - * multiple calls to #Append() with the pFinalize parameter set to false. - * This is finally required before one of #FindPositions() and #GenerateMappingTable() - * can be called to query the spatial sort.*/ - void Finalize(); - - // ------------------------------------------------------------------------------------ - /** Returns an iterator for all positions close to the given position. - * @param pPosition The position to look for vertices. - * @param pRadius Maximal distance from the position a vertex may have to be counted in. - * @param poResults The container to store the indices of the found positions. - * Will be emptied by the call so it may contain anything. - * @return An iterator to iterate over all vertices in the given area.*/ - void FindPositions( const aiVector3D& pPosition, ai_real pRadius, - std::vector<unsigned int>& poResults) const; - - // ------------------------------------------------------------------------------------ - /** Fills an array with indices of all positions identical to the given position. In - * opposite to FindPositions(), not an epsilon is used but a (very low) tolerance of - * four floating-point units. - * @param pPosition The position to look for vertices. - * @param poResults The container to store the indices of the found positions. - * Will be emptied by the call so it may contain anything.*/ - void FindIdenticalPositions( const aiVector3D& pPosition, - std::vector<unsigned int>& poResults) const; - - // ------------------------------------------------------------------------------------ - /** Compute a table that maps each vertex ID referring to a spatially close - * enough position to the same output ID. Output IDs are assigned in ascending order - * from 0...n. - * @param fill Will be filled with numPositions entries. - * @param pRadius Maximal distance from the position a vertex may have to - * be counted in. - * @return Number of unique vertices (n). */ - unsigned int GenerateMappingTable(std::vector<unsigned int>& fill, - ai_real pRadius) const; - -protected: - /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */ - aiVector3D mPlaneNormal; - - /** An entry in a spatially sorted position array. Consists of a vertex index, - * its position and its pre-calculated distance from the reference plane */ - struct Entry { - unsigned int mIndex; ///< The vertex referred by this entry - aiVector3D mPosition; ///< Position - ai_real mDistance; ///< Distance of this vertex to the sorting plane - - Entry() AI_NO_EXCEPT - : mIndex( 999999999 ), mPosition(), mDistance( 99999. ) { - // empty - } - Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance) - : mIndex( pIndex), mPosition( pPosition), mDistance( pDistance) { - // empty - } - - bool operator < (const Entry& e) const { return mDistance < e.mDistance; } - }; - - // all positions, sorted by distance to the sorting plane - std::vector<Entry> mPositions; -}; - -} // end of namespace Assimp - -#endif // AI_SPATIALSORT_H_INC diff --git a/thirdparty/assimp/include/assimp/StandardShapes.h b/thirdparty/assimp/include/assimp/StandardShapes.h deleted file mode 100644 index c594cb63f4..0000000000 --- a/thirdparty/assimp/include/assimp/StandardShapes.h +++ /dev/null @@ -1,205 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Declares a helper class, "StandardShapes" which generates - * vertices for standard shapes, such as cylinders, cones, spheres .. - */ -#pragma once -#ifndef AI_STANDARD_SHAPES_H_INC -#define AI_STANDARD_SHAPES_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/vector3.h> -#include <vector> - -struct aiMesh; - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** \brief Helper class to generate vertex buffers for standard geometric - * shapes, such as cylinders, cones, boxes, spheres, elipsoids ... . - */ -class ASSIMP_API StandardShapes -{ - // class cannot be instanced - StandardShapes() {} - -public: - - - // ---------------------------------------------------------------- - /** Generates a mesh from an array of vertex positions. - * - * @param positions List of vertex positions - * @param numIndices Number of indices per primitive - * @return Output mesh - */ - static aiMesh* MakeMesh(const std::vector<aiVector3D>& positions, - unsigned int numIndices); - - - static aiMesh* MakeMesh ( unsigned int (*GenerateFunc) - (std::vector<aiVector3D>&)); - - static aiMesh* MakeMesh ( unsigned int (*GenerateFunc) - (std::vector<aiVector3D>&, bool)); - - static aiMesh* MakeMesh ( unsigned int n, void (*GenerateFunc) - (unsigned int,std::vector<aiVector3D>&)); - - // ---------------------------------------------------------------- - /** @brief Generates a hexahedron (cube) - * - * Hexahedrons can be scaled on all axes. - * @param positions Receives output triangles. - * @param polygons If you pass true here quads will be returned - * @return Number of vertices per face - */ - static unsigned int MakeHexahedron( - std::vector<aiVector3D>& positions, - bool polygons = false); - - // ---------------------------------------------------------------- - /** @brief Generates an icosahedron - * - * @param positions Receives output triangles. - * @return Number of vertices per face - */ - static unsigned int MakeIcosahedron( - std::vector<aiVector3D>& positions); - - - // ---------------------------------------------------------------- - /** @brief Generates a dodecahedron - * - * @param positions Receives output triangles - * @param polygons If you pass true here pentagons will be returned - * @return Number of vertices per face - */ - static unsigned int MakeDodecahedron( - std::vector<aiVector3D>& positions, - bool polygons = false); - - - // ---------------------------------------------------------------- - /** @brief Generates an octahedron - * - * @param positions Receives output triangles. - * @return Number of vertices per face - */ - static unsigned int MakeOctahedron( - std::vector<aiVector3D>& positions); - - - // ---------------------------------------------------------------- - /** @brief Generates a tetrahedron - * - * @param positions Receives output triangles. - * @return Number of vertices per face - */ - static unsigned int MakeTetrahedron( - std::vector<aiVector3D>& positions); - - - - // ---------------------------------------------------------------- - /** @brief Generates a sphere - * - * @param tess Number of subdivions - 0 generates a octahedron - * @param positions Receives output triangles. - */ - static void MakeSphere(unsigned int tess, - std::vector<aiVector3D>& positions); - - - // ---------------------------------------------------------------- - /** @brief Generates a cone or a cylinder, either open or closed. - * - * @code - * - * |-----| <- radius 1 - * - * __x__ <- ] ^ - * / \ | height | - * / \ | Y - * / \ | - * / \ | - * /______x______\ <- ] <- end cap - * - * |-------------| <- radius 2 - * - * @endcode - * - * @param height Height of the cone - * @param radius1 First radius - * @param radius2 Second radius - * @param tess Number of triangles. - * @param bOpened true for an open cone/cylinder. An open shape has - * no 'end caps' - * @param positions Receives output triangles - */ - static void MakeCone(ai_real height,ai_real radius1, - ai_real radius2,unsigned int tess, - std::vector<aiVector3D>& positions,bool bOpen= false); - - - // ---------------------------------------------------------------- - /** @brief Generates a flat circle - * - * The circle is constructed in the planned formed by the x,z - * axes of the cartesian coordinate system. - * - * @param radius Radius of the circle - * @param tess Number of segments. - * @param positions Receives output triangles. - */ - static void MakeCircle(ai_real radius, unsigned int tess, - std::vector<aiVector3D>& positions); - -}; -} // ! Assimp - -#endif // !! AI_STANDARD_SHAPES_H_INC diff --git a/thirdparty/assimp/include/assimp/StreamReader.h b/thirdparty/assimp/include/assimp/StreamReader.h deleted file mode 100644 index cb24f1595b..0000000000 --- a/thirdparty/assimp/include/assimp/StreamReader.h +++ /dev/null @@ -1,347 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Defines the StreamReader class which reads data from - * a binary stream with a well-defined endianness. - */ -#pragma once -#ifndef AI_STREAMREADER_H_INCLUDED -#define AI_STREAMREADER_H_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/IOStream.hpp> -#include <assimp/Defines.h> -#include <assimp/ByteSwapper.h> -#include <assimp/Exceptional.h> - -#include <memory> - -namespace Assimp { - -// -------------------------------------------------------------------------------------------- -/** Wrapper class around IOStream to allow for consistent reading of binary data in both - * little and big endian format. Don't attempt to instance the template directly. Use - * StreamReaderLE to read from a little-endian stream and StreamReaderBE to read from a - * BE stream. The class expects that the endianness of any input data is known at - * compile-time, which should usually be true (#BaseImporter::ConvertToUTF8 implements - * runtime endianness conversions for text files). - * - * XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/ -// -------------------------------------------------------------------------------------------- -template <bool SwapEndianess = false, bool RuntimeSwitch = false> -class StreamReader { -public: - // FIXME: use these data types throughout the whole library, - // then change them to 64 bit values :-) - using diff = int; - using pos = unsigned int; - - // --------------------------------------------------------------------- - /** Construction from a given stream with a well-defined endianness. - * - * The StreamReader holds a permanent strong reference to the - * stream, which is released upon destruction. - * @param stream Input stream. The stream is not restarted if - * its file pointer is not at 0. Instead, the stream reader - * reads from the current position to the end of the stream. - * @param le If @c RuntimeSwitch is true: specifies whether the - * stream is in little endian byte order. Otherwise the - * endianness information is contained in the @c SwapEndianess - * template parameter and this parameter is meaningless. */ - StreamReader(std::shared_ptr<IOStream> stream, bool le = false) - : stream(stream) - , le(le) - { - ai_assert(stream); - InternBegin(); - } - - // --------------------------------------------------------------------- - StreamReader(IOStream* stream, bool le = false) - : stream(std::shared_ptr<IOStream>(stream)) - , le(le) - { - ai_assert(stream); - InternBegin(); - } - - // --------------------------------------------------------------------- - ~StreamReader() { - delete[] buffer; - } - - // deprecated, use overloaded operator>> instead - - // --------------------------------------------------------------------- - /** Read a float from the stream */ - float GetF4() - { - return Get<float>(); - } - - // --------------------------------------------------------------------- - /** Read a double from the stream */ - double GetF8() { - return Get<double>(); - } - - // --------------------------------------------------------------------- - /** Read a signed 16 bit integer from the stream */ - int16_t GetI2() { - return Get<int16_t>(); - } - - // --------------------------------------------------------------------- - /** Read a signed 8 bit integer from the stream */ - int8_t GetI1() { - return Get<int8_t>(); - } - - // --------------------------------------------------------------------- - /** Read an signed 32 bit integer from the stream */ - int32_t GetI4() { - return Get<int32_t>(); - } - - // --------------------------------------------------------------------- - /** Read a signed 64 bit integer from the stream */ - int64_t GetI8() { - return Get<int64_t>(); - } - - // --------------------------------------------------------------------- - /** Read a unsigned 16 bit integer from the stream */ - uint16_t GetU2() { - return Get<uint16_t>(); - } - - // --------------------------------------------------------------------- - /** Read a unsigned 8 bit integer from the stream */ - uint8_t GetU1() { - return Get<uint8_t>(); - } - - // --------------------------------------------------------------------- - /** Read an unsigned 32 bit integer from the stream */ - uint32_t GetU4() { - return Get<uint32_t>(); - } - - // --------------------------------------------------------------------- - /** Read a unsigned 64 bit integer from the stream */ - uint64_t GetU8() { - return Get<uint64_t>(); - } - - // --------------------------------------------------------------------- - /** Get the remaining stream size (to the end of the stream) */ - unsigned int GetRemainingSize() const { - return (unsigned int)(end - current); - } - - // --------------------------------------------------------------------- - /** Get the remaining stream size (to the current read limit). The - * return value is the remaining size of the stream if no custom - * read limit has been set. */ - unsigned int GetRemainingSizeToLimit() const { - return (unsigned int)(limit - current); - } - - // --------------------------------------------------------------------- - /** Increase the file pointer (relative seeking) */ - void IncPtr(intptr_t plus) { - current += plus; - if (current > limit) { - throw DeadlyImportError("End of file or read limit was reached"); - } - } - - // --------------------------------------------------------------------- - /** Get the current file pointer */ - int8_t* GetPtr() const { - return current; - } - - // --------------------------------------------------------------------- - /** Set current file pointer (Get it from #GetPtr). This is if you - * prefer to do pointer arithmetics on your own or want to copy - * large chunks of data at once. - * @param p The new pointer, which is validated against the size - * limit and buffer boundaries. */ - void SetPtr(int8_t* p) { - current = p; - if (current > limit || current < buffer) { - throw DeadlyImportError("End of file or read limit was reached"); - } - } - - // --------------------------------------------------------------------- - /** Copy n bytes to an external buffer - * @param out Destination for copying - * @param bytes Number of bytes to copy */ - void CopyAndAdvance(void* out, size_t bytes) { - int8_t* ur = GetPtr(); - SetPtr(ur+bytes); // fire exception if eof - - ::memcpy(out,ur,bytes); - } - - // --------------------------------------------------------------------- - /** Get the current offset from the beginning of the file */ - int GetCurrentPos() const { - return (unsigned int)(current - buffer); - } - - void SetCurrentPos(size_t pos) { - SetPtr(buffer + pos); - } - - // --------------------------------------------------------------------- - /** Setup a temporary read limit - * - * @param limit Maximum number of bytes to be read from - * the beginning of the file. Specifying UINT_MAX - * resets the limit to the original end of the stream. - * Returns the previously set limit. */ - unsigned int SetReadLimit(unsigned int _limit) { - unsigned int prev = GetReadLimit(); - if (UINT_MAX == _limit) { - limit = end; - return prev; - } - - limit = buffer + _limit; - if (limit > end) { - throw DeadlyImportError("StreamReader: Invalid read limit"); - } - return prev; - } - - // --------------------------------------------------------------------- - /** Get the current read limit in bytes. Reading over this limit - * accidentally raises an exception. */ - unsigned int GetReadLimit() const { - return (unsigned int)(limit - buffer); - } - - // --------------------------------------------------------------------- - /** Skip to the read limit in bytes. Reading over this limit - * accidentally raises an exception. */ - void SkipToReadLimit() { - current = limit; - } - - // --------------------------------------------------------------------- - /** overload operator>> and allow chaining of >> ops. */ - template <typename T> - StreamReader& operator >> (T& f) { - f = Get<T>(); - return *this; - } - - // --------------------------------------------------------------------- - /** Generic read method. ByteSwap::Swap(T*) *must* be defined */ - template <typename T> - T Get() { - if ( current + sizeof(T) > limit) { - throw DeadlyImportError("End of file or stream limit was reached"); - } - - T f; - ::memcpy (&f, current, sizeof(T)); - Intern::Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le); - current += sizeof(T); - - return f; - } - -private: - // --------------------------------------------------------------------- - void InternBegin() { - if (!stream) { - // in case someone wonders: StreamReader is frequently invoked with - // no prior validation whether the input stream is valid. Since - // no one bothers changing the error message, this message here - // is passed down to the caller and 'unable to open file' - // simply describes best what happened. - throw DeadlyImportError("StreamReader: Unable to open file"); - } - - const size_t s = stream->FileSize() - stream->Tell(); - if (!s) { - throw DeadlyImportError("StreamReader: File is empty or EOF is already reached"); - } - - current = buffer = new int8_t[s]; - const size_t read = stream->Read(current,1,s); - // (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable - ai_assert(read <= s); - end = limit = &buffer[read-1] + 1; - } - -private: - std::shared_ptr<IOStream> stream; - int8_t *buffer, *current, *end, *limit; - bool le; -}; - -// -------------------------------------------------------------------------------------------- -// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster. -#ifdef AI_BUILD_BIG_ENDIAN - typedef StreamReader<true> StreamReaderLE; - typedef StreamReader<false> StreamReaderBE; -#else - typedef StreamReader<true> StreamReaderBE; - typedef StreamReader<false> StreamReaderLE; -#endif - -// `dynamic` StreamReader. The byte order of the input data is specified in the -// c'tor. This involves runtime branching and might be a little bit slower. -typedef StreamReader<true,true> StreamReaderAny; - -} // end namespace Assimp - -#endif // !! AI_STREAMREADER_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/StreamWriter.h b/thirdparty/assimp/include/assimp/StreamWriter.h deleted file mode 100644 index 489e8adfe3..0000000000 --- a/thirdparty/assimp/include/assimp/StreamWriter.h +++ /dev/null @@ -1,307 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Defines the StreamWriter class which writes data to - * a binary stream with a well-defined endianness. */ -#pragma once -#ifndef AI_STREAMWRITER_H_INCLUDED -#define AI_STREAMWRITER_H_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/ByteSwapper.h> -#include <assimp/IOStream.hpp> - -#include <memory> -#include <vector> - -namespace Assimp { - -// -------------------------------------------------------------------------------------------- -/** Wrapper class around IOStream to allow for consistent writing of binary data in both - * little and big endian format. Don't attempt to instance the template directly. Use - * StreamWriterLE to write to a little-endian stream and StreamWriterBE to write to a - * BE stream. Alternatively, there is StreamWriterAny if the endianness of the output - * stream is to be determined at runtime. - */ -// -------------------------------------------------------------------------------------------- -template <bool SwapEndianess = false, bool RuntimeSwitch = false> -class StreamWriter -{ - enum { - INITIAL_CAPACITY = 1024 - }; - -public: - - // --------------------------------------------------------------------- - /** Construction from a given stream with a well-defined endianness. - * - * The StreamReader holds a permanent strong reference to the - * stream, which is released upon destruction. - * @param stream Input stream. The stream is not re-seeked and writing - continues at the current position of the stream cursor. - * @param le If @c RuntimeSwitch is true: specifies whether the - * stream is in little endian byte order. Otherwise the - * endianness information is defined by the @c SwapEndianess - * template parameter and this parameter is meaningless. */ - StreamWriter(std::shared_ptr<IOStream> stream, bool le = false) - : stream(stream) - , le(le) - , cursor() - { - ai_assert(stream); - buffer.reserve(INITIAL_CAPACITY); - } - - // --------------------------------------------------------------------- - StreamWriter(IOStream* stream, bool le = false) - : stream(std::shared_ptr<IOStream>(stream)) - , le(le) - , cursor() - { - ai_assert(stream); - buffer.reserve(INITIAL_CAPACITY); - } - - // --------------------------------------------------------------------- - ~StreamWriter() { - stream->Write(buffer.data(), 1, buffer.size()); - stream->Flush(); - } - -public: - - // --------------------------------------------------------------------- - /** Flush the contents of the internal buffer, and the output IOStream */ - void Flush() - { - stream->Write(buffer.data(), 1, buffer.size()); - stream->Flush(); - buffer.clear(); - cursor = 0; - } - - // --------------------------------------------------------------------- - /** Seek to the given offset / origin in the output IOStream. - * - * Flushes the internal buffer and the output IOStream prior to seeking. */ - aiReturn Seek(size_t pOffset, aiOrigin pOrigin=aiOrigin_SET) - { - Flush(); - return stream->Seek(pOffset, pOrigin); - } - - // --------------------------------------------------------------------- - /** Tell the current position in the output IOStream. - * - * First flushes the internal buffer and the output IOStream. */ - size_t Tell() - { - Flush(); - return stream->Tell(); - } - -public: - - // --------------------------------------------------------------------- - /** Write a float to the stream */ - void PutF4(float f) - { - Put(f); - } - - // --------------------------------------------------------------------- - /** Write a double to the stream */ - void PutF8(double d) { - Put(d); - } - - // --------------------------------------------------------------------- - /** Write a signed 16 bit integer to the stream */ - void PutI2(int16_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write a signed 8 bit integer to the stream */ - void PutI1(int8_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write an signed 32 bit integer to the stream */ - void PutI4(int32_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write a signed 64 bit integer to the stream */ - void PutI8(int64_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write a unsigned 16 bit integer to the stream */ - void PutU2(uint16_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write a unsigned 8 bit integer to the stream */ - void PutU1(uint8_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write an unsigned 32 bit integer to the stream */ - void PutU4(uint32_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write a unsigned 64 bit integer to the stream */ - void PutU8(uint64_t n) { - Put(n); - } - - // --------------------------------------------------------------------- - /** Write a single character to the stream */ - void PutChar(char c) { - Put(c); - } - - // --------------------------------------------------------------------- - /** Write an aiString to the stream */ - void PutString(const aiString& s) - { - // as Put(T f) below - if (cursor + s.length >= buffer.size()) { - buffer.resize(cursor + s.length); - } - void* dest = &buffer[cursor]; - ::memcpy(dest, s.C_Str(), s.length); - cursor += s.length; - } - - // --------------------------------------------------------------------- - /** Write a std::string to the stream */ - void PutString(const std::string& s) - { - // as Put(T f) below - if (cursor + s.size() >= buffer.size()) { - buffer.resize(cursor + s.size()); - } - void* dest = &buffer[cursor]; - ::memcpy(dest, s.c_str(), s.size()); - cursor += s.size(); - } - -public: - - // --------------------------------------------------------------------- - /** overload operator<< and allow chaining of MM ops. */ - template <typename T> - StreamWriter& operator << (T f) { - Put(f); - return *this; - } - - // --------------------------------------------------------------------- - std::size_t GetCurrentPos() const { - return cursor; - } - - // --------------------------------------------------------------------- - void SetCurrentPos(std::size_t new_cursor) { - cursor = new_cursor; - } - - // --------------------------------------------------------------------- - /** Generic write method. ByteSwap::Swap(T*) *must* be defined */ - template <typename T> - void Put(T f) { - Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f, le); - - if (cursor + sizeof(T) >= buffer.size()) { - buffer.resize(cursor + sizeof(T)); - } - - void* dest = &buffer[cursor]; - - // reinterpret_cast + assignment breaks strict aliasing rules - // and generally causes trouble on platforms such as ARM that - // do not silently ignore alignment faults. - ::memcpy(dest, &f, sizeof(T)); - cursor += sizeof(T); - } - -private: - - std::shared_ptr<IOStream> stream; - bool le; - - std::vector<uint8_t> buffer; - std::size_t cursor; -}; - - -// -------------------------------------------------------------------------------------------- -// `static` StreamWriter. Their byte order is fixed and they might be a little bit faster. -#ifdef AI_BUILD_BIG_ENDIAN - typedef StreamWriter<true> StreamWriterLE; - typedef StreamWriter<false> StreamWriterBE; -#else - typedef StreamWriter<true> StreamWriterBE; - typedef StreamWriter<false> StreamWriterLE; -#endif - -// `dynamic` StreamWriter. The byte order of the input data is specified in the -// c'tor. This involves runtime branching and might be a little bit slower. -typedef StreamWriter<true,true> StreamWriterAny; - -} // end namespace Assimp - -#endif // !! AI_STREAMWriter_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/StringComparison.h b/thirdparty/assimp/include/assimp/StringComparison.h deleted file mode 100644 index d3ca3e9714..0000000000 --- a/thirdparty/assimp/include/assimp/StringComparison.h +++ /dev/null @@ -1,238 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Definition of platform independent string workers: - - ASSIMP_itoa10 - ASSIMP_stricmp - ASSIMP_strincmp - - These functions are not consistently available on all platforms, - or the provided implementations behave too differently. -*/ -#pragma once -#ifndef INCLUDED_AI_STRING_WORKERS_H -#define INCLUDED_AI_STRING_WORKERS_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/ai_assert.h> -#include <assimp/defs.h> -#include <assimp/StringComparison.h> - -#include <string.h> -#include <stdint.h> -#include <string> - -namespace Assimp { - -// ------------------------------------------------------------------------------- -/** @brief itoa with a fixed base 10 - * 'itoa' is not consistently available on all platforms so it is quite useful - * to have a small replacement function here. No need to use a full sprintf() - * if we just want to print a number ... - * @param out Output buffer - * @param max Maximum number of characters to be written, including '\0'. - * This parameter may not be 0. - * @param number Number to be written - * @return Length of the output string, excluding the '\0' - */ -AI_FORCE_INLINE -unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number) { - ai_assert(NULL != out); - - // write the unary minus to indicate we have a negative number - unsigned int written = 1u; - if (number < 0 && written < max) { - *out++ = '-'; - ++written; - number = -number; - } - - // We begin with the largest number that is not zero. - int32_t cur = 1000000000; // 2147483648 - bool mustPrint = false; - while (written < max) { - - const unsigned int digit = number / cur; - if (mustPrint || digit > 0 || 1 == cur) { - // print all future zeroe's from now - mustPrint = true; - - *out++ = '0'+static_cast<char>(digit); - - ++written; - number -= digit*cur; - if (1 == cur) { - break; - } - } - cur /= 10; - } - - // append a terminal zero - *out++ = '\0'; - return written-1; -} - -// ------------------------------------------------------------------------------- -/** @brief itoa with a fixed base 10 (Secure template overload) - * The compiler should choose this function if he or she is able to determine the - * size of the array automatically. - */ -template <size_t length> -AI_FORCE_INLINE -unsigned int ASSIMP_itoa10( char(& out)[length], int32_t number) { - return ASSIMP_itoa10(out,length,number); -} - -// ------------------------------------------------------------------------------- -/** @brief Helper function to do platform independent string comparison. - * - * This is required since stricmp() is not consistently available on - * all platforms. Some platforms use the '_' prefix, others don't even - * have such a function. - * - * @param s1 First input string - * @param s2 Second input string - * @return 0 if the given strings are identical - */ -AI_FORCE_INLINE -int ASSIMP_stricmp(const char *s1, const char *s2) { - ai_assert( NULL != s1 ); - ai_assert( NULL != s2 ); - -#if (defined _MSC_VER) - - return ::_stricmp(s1,s2); -#elif defined( __GNUC__ ) - - return ::strcasecmp(s1,s2); -#else - - char c1, c2; - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } - while ( c1 && (c1 == c2) ); - return c1 - c2; -#endif -} - -// ------------------------------------------------------------------------------- -/** @brief Case independent comparison of two std::strings - * - * @param a First string - * @param b Second string - * @return 0 if a == b - */ -AI_FORCE_INLINE -int ASSIMP_stricmp(const std::string& a, const std::string& b) { - int i = (int)b.length()-(int)a.length(); - return (i ? i : ASSIMP_stricmp(a.c_str(),b.c_str())); -} - -// ------------------------------------------------------------------------------- -/** @brief Helper function to do platform independent string comparison. - * - * This is required since strincmp() is not consistently available on - * all platforms. Some platforms use the '_' prefix, others don't even - * have such a function. - * - * @param s1 First input string - * @param s2 Second input string - * @param n Macimum number of characters to compare - * @return 0 if the given strings are identical - */ -AI_FORCE_INLINE -int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) { - ai_assert( NULL != s1 ); - ai_assert( NULL != s2 ); - if ( !n ) { - return 0; - } - -#if (defined _MSC_VER) - - return ::_strnicmp(s1,s2,n); - -#elif defined( __GNUC__ ) - - return ::strncasecmp(s1,s2, n); - -#else - char c1, c2; - unsigned int p = 0; - do - { - if (p++ >= n)return 0; - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } - while ( c1 && (c1 == c2) ); - - return c1 - c2; -#endif -} - - -// ------------------------------------------------------------------------------- -/** @brief Evaluates an integer power - * - * todo: move somewhere where it fits better in than here - */ -AI_FORCE_INLINE -unsigned int integer_pow( unsigned int base, unsigned int power ) { - unsigned int res = 1; - for ( unsigned int i = 0; i < power; ++i ) { - res *= base; - } - - return res; -} - -} // end of namespace - -#endif // ! AI_STRINGCOMPARISON_H_INC diff --git a/thirdparty/assimp/include/assimp/StringUtils.h b/thirdparty/assimp/include/assimp/StringUtils.h deleted file mode 100644 index af481f819e..0000000000 --- a/thirdparty/assimp/include/assimp/StringUtils.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#pragma once -#ifndef INCLUDED_AI_STRINGUTILS_H -#define INCLUDED_AI_STRINGUTILS_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/defs.h> - -#include <sstream> -#include <stdarg.h> -#include <cstdlib> - -/// @fn ai_snprintf -/// @brief The portable version of the function snprintf ( C99 standard ), which works on visual studio compilers 2013 and earlier. -/// @param outBuf The buffer to write in -/// @param size The buffer size -/// @param format The format string -/// @param ap The additional arguments. -/// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned. -#if defined(_MSC_VER) && _MSC_VER < 1900 - - AI_FORCE_INLINE - int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { - int count(-1); - if (0 != size) { - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); - } - if (count == -1) { - count = _vscprintf(format, ap); - } - - return count; - } - - AI_FORCE_INLINE - int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { - int count; - va_list ap; - - va_start(ap, format); - count = c99_ai_vsnprintf(outBuf, size, format, ap); - va_end(ap); - - return count; - } - -#else -# define ai_snprintf snprintf -#endif - -/// @fn to_string -/// @brief The portable version of to_string ( some gcc-versions on embedded devices are not supporting this). -/// @param value The value to write into the std::string. -/// @return The value as a std::string -template <typename T> -AI_FORCE_INLINE -std::string to_string( T value ) { - std::ostringstream os; - os << value; - - return os.str(); -} - -/// @fn ai_strtof -/// @brief The portable version of strtof. -/// @param begin The first character of the string. -/// @param end The last character -/// @return The float value, 0.0f in cas of an error. -AI_FORCE_INLINE -float ai_strtof( const char *begin, const char *end ) { - if ( nullptr == begin ) { - return 0.0f; - } - float val( 0.0f ); - if ( nullptr == end ) { - val = static_cast< float >( ::atof( begin ) ); - } else { - std::string::size_type len( end - begin ); - std::string token( begin, len ); - val = static_cast< float >( ::atof( token.c_str() ) ); - } - - return val; -} - -/// @fn DecimalToHexa -/// @brief The portable to convert a decimal value into a hexadecimal string. -/// @param toConvert Value to convert -/// @return The hexadecimal string, is empty in case of an error. -template<class T> -AI_FORCE_INLINE -std::string DecimalToHexa( T toConvert ) { - std::string result; - std::stringstream ss; - ss << std::hex << toConvert; - ss >> result; - - for ( size_t i = 0; i < result.size(); ++i ) { - result[ i ] = toupper( result[ i ] ); - } - - return result; -} - -#endif // INCLUDED_AI_STRINGUTILS_H diff --git a/thirdparty/assimp/include/assimp/Subdivision.h b/thirdparty/assimp/include/assimp/Subdivision.h deleted file mode 100644 index e9450267ec..0000000000 --- a/thirdparty/assimp/include/assimp/Subdivision.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines a helper class to evaluate subdivision surfaces.*/ -#pragma once -#ifndef AI_SUBDISIVION_H_INC -#define AI_SUBDISIVION_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -struct aiMesh; - -namespace Assimp { - -// ------------------------------------------------------------------------------ -/** Helper class to evaluate subdivision surfaces. Different algorithms - * are provided for choice. */ -// ------------------------------------------------------------------------------ -class ASSIMP_API Subdivider { -public: - - /** Enumerates all supported subvidision algorithms */ - enum Algorithm { - CATMULL_CLARKE = 0x1 - }; - - virtual ~Subdivider(); - - // --------------------------------------------------------------- - /** Create a subdivider of a specific type - * - * @param algo Algorithm to be used for subdivision - * @return Subdivider instance. */ - static Subdivider* Create (Algorithm algo); - - // --------------------------------------------------------------- - /** Subdivide a mesh using the selected algorithm - * - * @param mesh First mesh to be subdivided. Must be in verbose - * format. - * @param out Receives the output mesh, allocated by me. - * @param num Number of subdivisions to perform. - * @param discard_input If true is passed, the input mesh is - * deleted after the subdivision is complete. This can - * improve performance because it allows the optimization - * to reuse the existing mesh for intermediate results. - * @pre out!=mesh*/ - virtual void Subdivide ( aiMesh* mesh, - aiMesh*& out, unsigned int num, - bool discard_input = false) = 0; - - // --------------------------------------------------------------- - /** Subdivide multiple meshes using the selected algorithm. This - * avoids erroneous smoothing on objects consisting of multiple - * per-material meshes. Usually, most 3d modellers smooth on a - * per-object base, regardless the materials assigned to the - * meshes. - * - * @param smesh Array of meshes to be subdivided. Must be in - * verbose format. - * @param nmesh Number of meshes in smesh. - * @param out Receives the output meshes. The array must be - * sufficiently large (at least @c nmesh elements) and may not - * overlap the input array. Output meshes map one-to-one to - * their corresponding input meshes. The meshes are allocated - * by the function. - * @param discard_input If true is passed, input meshes are - * deleted after the subdivision is complete. This can - * improve performance because it allows the optimization - * of reusing existing meshes for intermediate results. - * @param num Number of subdivisions to perform. - * @pre nmesh != 0, smesh and out may not overlap*/ - virtual void Subdivide ( - aiMesh** smesh, - size_t nmesh, - aiMesh** out, - unsigned int num, - bool discard_input = false) = 0; - -}; - -inline -Subdivider::~Subdivider() { - // empty -} - -} // end namespace Assimp - - -#endif // !! AI_SUBDISIVION_H_INC - diff --git a/thirdparty/assimp/include/assimp/TinyFormatter.h b/thirdparty/assimp/include/assimp/TinyFormatter.h deleted file mode 100644 index 6227e42c52..0000000000 --- a/thirdparty/assimp/include/assimp/TinyFormatter.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file TinyFormatter.h - * @brief Utility to format log messages more easily. Introduced - * to get rid of the boost::format dependency. Much slinker, - * basically just extends stringstream. - */ -#pragma once -#ifndef INCLUDED_TINY_FORMATTER_H -#define INCLUDED_TINY_FORMATTER_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <sstream> - -namespace Assimp { -namespace Formatter { - -// ------------------------------------------------------------------------------------------------ -/** stringstream utility. Usage: - * @code - * void writelog(const std::string&s); - * void writelog(const std::wstring&s); - * ... - * writelog(format()<< "hi! this is a number: " << 4); - * writelog(wformat()<< L"hi! this is a number: " << 4); - * - * @endcode */ -template < typename T, - typename CharTraits = std::char_traits<T>, - typename Allocator = std::allocator<T> > -class basic_formatter { -public: - typedef class std::basic_string<T,CharTraits,Allocator> string; - typedef class std::basic_ostringstream<T,CharTraits,Allocator> stringstream; - - basic_formatter() { - // empty - } - - /* Allow basic_formatter<T>'s to be used almost interchangeably - * with std::(w)string or const (w)char* arguments because the - * conversion c'tor is called implicitly. */ - template <typename TT> - basic_formatter(const TT& sin) { - underlying << sin; - } - - - // The problem described here: - // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 - // can also cause trouble here. Apparently, older gcc versions sometimes copy temporaries - // being bound to const ref& function parameters. Copying streams is not permitted, though. - // This workaround avoids this by manually specifying a copy ctor. -#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) - explicit basic_formatter(const basic_formatter& other) { - underlying << (string)other; - } -#endif - - operator string () const { - return underlying.str(); - } - - /* note - this is declared const because binding temporaries does only - * work for const references, so many function prototypes will - * include const basic_formatter<T>& s but might still want to - * modify the formatted string without the need for a full copy.*/ - template <typename TToken> - const basic_formatter& operator << (const TToken& s) const { - underlying << s; - return *this; - } - - template <typename TToken> - basic_formatter& operator << (const TToken& s) { - underlying << s; - return *this; - } - - - // comma operator overloaded as well, choose your preferred way. - template <typename TToken> - const basic_formatter& operator, (const TToken& s) const { - underlying << s; - return *this; - } - - template <typename TToken> - basic_formatter& operator, (const TToken& s) { - underlying << s; - return *this; - } - - // Fix for MSVC8 - // See https://sourceforge.net/projects/assimp/forums/forum/817654/topic/4372824 - template <typename TToken> - basic_formatter& operator, (TToken& s) { - underlying << s; - return *this; - } - - -private: - mutable stringstream underlying; -}; - - -typedef basic_formatter< char > format; -typedef basic_formatter< wchar_t > wformat; - -} // ! namespace Formatter - -} // ! namespace Assimp - -#endif diff --git a/thirdparty/assimp/include/assimp/Vertex.h b/thirdparty/assimp/include/assimp/Vertex.h deleted file mode 100644 index 5e63db5fe4..0000000000 --- a/thirdparty/assimp/include/assimp/Vertex.h +++ /dev/null @@ -1,297 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -/** @file Defines a helper class to represent an interleaved vertex - along with arithmetic operations to support vertex operations - such as subdivision, smoothing etc. - - While the code is kept as general as possible, arithmetic operations - that are not currently well-defined (and would cause compile errors - due to missing operators in the math library), are commented. - */ -#pragma once -#ifndef AI_VERTEX_H_INC -#define AI_VERTEX_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/vector3.h> -#include <assimp/mesh.h> -#include <assimp/ai_assert.h> - -#include <functional> - -namespace Assimp { - - /////////////////////////////////////////////////////////////////////////// - // std::plus-family operates on operands with identical types - we need to - // support all the (vectype op float) combinations in vector maths. - // Providing T(float) would open the way to endless implicit conversions. - /////////////////////////////////////////////////////////////////////////// - namespace Intern { - template <typename T0, typename T1, typename TRES = T0> struct plus { - TRES operator() (const T0& t0, const T1& t1) const { - return t0+t1; - } - }; - template <typename T0, typename T1, typename TRES = T0> struct minus { - TRES operator() (const T0& t0, const T1& t1) const { - return t0-t1; - } - }; - template <typename T0, typename T1, typename TRES = T0> struct multiplies { - TRES operator() (const T0& t0, const T1& t1) const { - return t0*t1; - } - }; - template <typename T0, typename T1, typename TRES = T0> struct divides { - TRES operator() (const T0& t0, const T1& t1) const { - return t0/t1; - } - }; - } - -// ------------------------------------------------------------------------------------------------ -/** Intermediate description a vertex with all possible components. Defines a full set of - * operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied - * to *all* vertex components equally. This is useful for stuff like interpolation - * or subdivision, but won't work if special handling is required for some vertex components. */ -// ------------------------------------------------------------------------------------------------ -class Vertex { - friend Vertex operator + (const Vertex&,const Vertex&); - friend Vertex operator - (const Vertex&,const Vertex&); - friend Vertex operator * (const Vertex&,ai_real); - friend Vertex operator / (const Vertex&,ai_real); - friend Vertex operator * (ai_real, const Vertex&); - -public: - Vertex() {} - - // ---------------------------------------------------------------------------- - /** Extract a particular vertex from a mesh and interleave all components */ - explicit Vertex(const aiMesh* msh, unsigned int idx) { - ai_assert(idx < msh->mNumVertices); - position = msh->mVertices[idx]; - - if (msh->HasNormals()) { - normal = msh->mNormals[idx]; - } - - if (msh->HasTangentsAndBitangents()) { - tangent = msh->mTangents[idx]; - bitangent = msh->mBitangents[idx]; - } - - for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { - texcoords[i] = msh->mTextureCoords[i][idx]; - } - - for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { - colors[i] = msh->mColors[i][idx]; - } - } - - // ---------------------------------------------------------------------------- - /** Extract a particular vertex from a anim mesh and interleave all components */ - explicit Vertex(const aiAnimMesh* msh, unsigned int idx) { - ai_assert(idx < msh->mNumVertices); - position = msh->mVertices[idx]; - - if (msh->HasNormals()) { - normal = msh->mNormals[idx]; - } - - if (msh->HasTangentsAndBitangents()) { - tangent = msh->mTangents[idx]; - bitangent = msh->mBitangents[idx]; - } - - for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { - texcoords[i] = msh->mTextureCoords[i][idx]; - } - - for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { - colors[i] = msh->mColors[i][idx]; - } - } - - Vertex& operator += (const Vertex& v) { - *this = *this+v; - return *this; - } - - Vertex& operator -= (const Vertex& v) { - *this = *this-v; - return *this; - } - - Vertex& operator *= (ai_real v) { - *this = *this*v; - return *this; - } - - Vertex& operator /= (ai_real v) { - *this = *this/v; - return *this; - } - - // ---------------------------------------------------------------------------- - /** Convert back to non-interleaved storage */ - void SortBack(aiMesh* out, unsigned int idx) const { - ai_assert(idx<out->mNumVertices); - out->mVertices[idx] = position; - - if (out->HasNormals()) { - out->mNormals[idx] = normal; - } - - if (out->HasTangentsAndBitangents()) { - out->mTangents[idx] = tangent; - out->mBitangents[idx] = bitangent; - } - - for(unsigned int i = 0; out->HasTextureCoords(i); ++i) { - out->mTextureCoords[i][idx] = texcoords[i]; - } - - for(unsigned int i = 0; out->HasVertexColors(i); ++i) { - out->mColors[i][idx] = colors[i]; - } - } - -private: - - // ---------------------------------------------------------------------------- - /** Construct from two operands and a binary operation to combine them */ - template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) { - // this is a heavy task for the compiler to optimize ... *pray* - - Vertex res; - res.position = op<aiVector3D>()(v0.position,v1.position); - res.normal = op<aiVector3D>()(v0.normal,v1.normal); - res.tangent = op<aiVector3D>()(v0.tangent,v1.tangent); - res.bitangent = op<aiVector3D>()(v0.bitangent,v1.bitangent); - - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - res.texcoords[i] = op<aiVector3D>()(v0.texcoords[i],v1.texcoords[i]); - } - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { - res.colors[i] = op<aiColor4D>()(v0.colors[i],v1.colors[i]); - } - return res; - } - - // ---------------------------------------------------------------------------- - /** This time binary arithmetics of v0 with a floating-point number */ - template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) { - // this is a heavy task for the compiler to optimize ... *pray* - - Vertex res; - res.position = op<aiVector3D,ai_real,aiVector3D>()(v0.position,f); - res.normal = op<aiVector3D,ai_real,aiVector3D>()(v0.normal,f); - res.tangent = op<aiVector3D,ai_real,aiVector3D>()(v0.tangent,f); - res.bitangent = op<aiVector3D,ai_real,aiVector3D>()(v0.bitangent,f); - - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - res.texcoords[i] = op<aiVector3D,ai_real,aiVector3D>()(v0.texcoords[i],f); - } - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { - res.colors[i] = op<aiColor4D,ai_real,aiColor4D>()(v0.colors[i],f); - } - return res; - } - - // ---------------------------------------------------------------------------- - /** This time binary arithmetics of v0 with a floating-point number */ - template <template <typename, typename, typename> class op> static Vertex BinaryOp(ai_real f, const Vertex& v0) { - // this is a heavy task for the compiler to optimize ... *pray* - - Vertex res; - res.position = op<ai_real,aiVector3D,aiVector3D>()(f,v0.position); - res.normal = op<ai_real,aiVector3D,aiVector3D>()(f,v0.normal); - res.tangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.tangent); - res.bitangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.bitangent); - - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - res.texcoords[i] = op<ai_real,aiVector3D,aiVector3D>()(f,v0.texcoords[i]); - } - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { - res.colors[i] = op<ai_real,aiColor4D,aiColor4D>()(f,v0.colors[i]); - } - return res; - } - -public: - - aiVector3D position; - aiVector3D normal; - aiVector3D tangent, bitangent; - - aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS]; -}; - -// ------------------------------------------------------------------------------------------------ -AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) { - return Vertex::BinaryOp<std::plus>(v0,v1); -} - -AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) { - return Vertex::BinaryOp<std::minus>(v0,v1); -} - -AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) { - return Vertex::BinaryOp<Intern::multiplies>(v0,f); -} - -AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) { - return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f); -} - -AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) { - return Vertex::BinaryOp<Intern::multiplies>(f,v0); -} - -} - -#endif // AI_VERTEX_H_INC diff --git a/thirdparty/assimp/include/assimp/XMLTools.h b/thirdparty/assimp/include/assimp/XMLTools.h deleted file mode 100644 index 95f12cdebf..0000000000 --- a/thirdparty/assimp/include/assimp/XMLTools.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#pragma once -#ifndef INCLUDED_ASSIMP_XML_TOOLS_H -#define INCLUDED_ASSIMP_XML_TOOLS_H - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <string> - -namespace Assimp { - // XML escape the 5 XML special characters (",',<,> and &) in |data| - // Based on http://stackoverflow.com/questions/5665231 - std::string XMLEscape(const std::string& data) { - std::string buffer; - - const size_t size = data.size(); - buffer.reserve(size + size / 8); - for(size_t i = 0; i < size; ++i) { - const char c = data[i]; - switch(c) { - case '&' : - buffer.append("&"); - break; - case '\"': - buffer.append("""); - break; - case '\'': - buffer.append("'"); - break; - case '<' : - buffer.append("<"); - break; - case '>' : - buffer.append(">"); - break; - default: - buffer.append(&c, 1); - break; - } - } - return buffer; - } -} - -#endif // INCLUDED_ASSIMP_XML_TOOLS_H diff --git a/thirdparty/assimp/include/assimp/aabb.h b/thirdparty/assimp/include/assimp/aabb.h deleted file mode 100644 index 83bb62256b..0000000000 --- a/thirdparty/assimp/include/assimp/aabb.h +++ /dev/null @@ -1,79 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -#pragma once -#ifndef AI_AABB_H_INC -#define AI_AABB_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/vector3.h> - -struct aiAABB { - C_STRUCT aiVector3D mMin; - C_STRUCT aiVector3D mMax; - -#ifdef __cplusplus - - aiAABB() - : mMin() - , mMax() { - // empty - } - - aiAABB(const aiVector3D &min, const aiVector3D &max ) - : mMin(min) - , mMax(max) { - // empty - } - - ~aiAABB() { - // empty - } - -#endif // __cplusplus - -}; - - -#endif // AI_AABB_H_INC diff --git a/thirdparty/assimp/include/assimp/ai_assert.h b/thirdparty/assimp/include/assimp/ai_assert.h deleted file mode 100644 index 2b32b01d3e..0000000000 --- a/thirdparty/assimp/include/assimp/ai_assert.h +++ /dev/null @@ -1,61 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -#pragma once -#ifndef AI_ASSERT_H_INC -#define AI_ASSERT_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef ASSIMP_BUILD_DEBUG -# include <assert.h> -# define ai_assert(expression) assert( expression ) -# define ai_assert_entry() assert( false ) -#else -# define ai_assert(expression) -# define ai_assert_entry() -#endif // ASSIMP_BUILD_DEBUG - -#endif // AI_ASSERT_H_INC - diff --git a/thirdparty/assimp/include/assimp/anim.h b/thirdparty/assimp/include/assimp/anim.h deleted file mode 100644 index e208b11adb..0000000000 --- a/thirdparty/assimp/include/assimp/anim.h +++ /dev/null @@ -1,581 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** - * @file anim.h - * @brief Defines the data structures in which the imported animations - * are returned. - */ -#pragma once -#ifndef AI_ANIM_H_INC -#define AI_ANIM_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> -#include <assimp/quaternion.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------------- -/** A time-value pair specifying a certain 3D vector for the given time. */ -struct aiVectorKey -{ - /** The time of this key */ - double mTime; - - /** The value of this key */ - C_STRUCT aiVector3D mValue; - -#ifdef __cplusplus - - /// @brief The default constructor. - aiVectorKey() AI_NO_EXCEPT - : mTime( 0.0 ) - , mValue() { - // empty - } - - /// @brief Construction from a given time and key value. - - aiVectorKey(double time, const aiVector3D& value) - : mTime( time ) - , mValue( value ) { - // empty - } - - typedef aiVector3D elem_type; - - // Comparison operators. For use with std::find(); - bool operator == (const aiVectorKey& rhs) const { - return rhs.mValue == this->mValue; - } - bool operator != (const aiVectorKey& rhs ) const { - return rhs.mValue != this->mValue; - } - - // Relational operators. For use with std::sort(); - bool operator < (const aiVectorKey& rhs ) const { - return mTime < rhs.mTime; - } - bool operator > (const aiVectorKey& rhs ) const { - return mTime > rhs.mTime; - } -#endif // __cplusplus -}; - -// --------------------------------------------------------------------------- -/** A time-value pair specifying a rotation for the given time. - * Rotations are expressed with quaternions. */ -struct aiQuatKey -{ - /** The time of this key */ - double mTime; - - /** The value of this key */ - C_STRUCT aiQuaternion mValue; - -#ifdef __cplusplus - aiQuatKey() AI_NO_EXCEPT - : mTime( 0.0 ) - , mValue() { - // empty - } - - /** Construction from a given time and key value */ - aiQuatKey(double time, const aiQuaternion& value) - : mTime (time) - , mValue (value) - {} - - typedef aiQuaternion elem_type; - - // Comparison operators. For use with std::find(); - bool operator == (const aiQuatKey& rhs ) const { - return rhs.mValue == this->mValue; - } - bool operator != (const aiQuatKey& rhs ) const { - return rhs.mValue != this->mValue; - } - - // Relational operators. For use with std::sort(); - bool operator < (const aiQuatKey& rhs ) const { - return mTime < rhs.mTime; - } - bool operator > (const aiQuatKey& rhs ) const { - return mTime > rhs.mTime; - } -#endif -}; - -// --------------------------------------------------------------------------- -/** Binds a anim-mesh to a specific point in time. */ -struct aiMeshKey -{ - /** The time of this key */ - double mTime; - - /** Index into the aiMesh::mAnimMeshes array of the - * mesh corresponding to the #aiMeshAnim hosting this - * key frame. The referenced anim mesh is evaluated - * according to the rules defined in the docs for #aiAnimMesh.*/ - unsigned int mValue; - -#ifdef __cplusplus - - aiMeshKey() AI_NO_EXCEPT - : mTime(0.0) - , mValue(0) - { - } - - /** Construction from a given time and key value */ - aiMeshKey(double time, const unsigned int value) - : mTime (time) - , mValue (value) - {} - - typedef unsigned int elem_type; - - // Comparison operators. For use with std::find(); - bool operator == (const aiMeshKey& o) const { - return o.mValue == this->mValue; - } - bool operator != (const aiMeshKey& o) const { - return o.mValue != this->mValue; - } - - // Relational operators. For use with std::sort(); - bool operator < (const aiMeshKey& o) const { - return mTime < o.mTime; - } - bool operator > (const aiMeshKey& o) const { - return mTime > o.mTime; - } - -#endif -}; - -// --------------------------------------------------------------------------- -/** Binds a morph anim mesh to a specific point in time. */ -struct aiMeshMorphKey -{ - /** The time of this key */ - double mTime; - - /** The values and weights at the time of this key */ - unsigned int *mValues; - double *mWeights; - - /** The number of values and weights */ - unsigned int mNumValuesAndWeights; -#ifdef __cplusplus - aiMeshMorphKey() AI_NO_EXCEPT - : mTime(0.0) - , mValues(nullptr) - , mWeights(nullptr) - , mNumValuesAndWeights(0) - { - - } - - ~aiMeshMorphKey() - { - if (mNumValuesAndWeights && mValues && mWeights) { - delete [] mValues; - delete [] mWeights; - } - } -#endif -}; - -// --------------------------------------------------------------------------- -/** Defines how an animation channel behaves outside the defined time - * range. This corresponds to aiNodeAnim::mPreState and - * aiNodeAnim::mPostState.*/ -enum aiAnimBehaviour -{ - /** The value from the default node transformation is taken*/ - aiAnimBehaviour_DEFAULT = 0x0, - - /** The nearest key value is used without interpolation */ - aiAnimBehaviour_CONSTANT = 0x1, - - /** The value of the nearest two keys is linearly - * extrapolated for the current time value.*/ - aiAnimBehaviour_LINEAR = 0x2, - - /** The animation is repeated. - * - * If the animation key go from n to m and the current - * time is t, use the value at (t-n) % (|m-n|).*/ - aiAnimBehaviour_REPEAT = 0x3, - - /** This value is not used, it is just here to force the - * the compiler to map this enum to a 32 Bit integer */ -#ifndef SWIG - _aiAnimBehaviour_Force32Bit = INT_MAX -#endif -}; - -// --------------------------------------------------------------------------- -/** Describes the animation of a single node. The name specifies the - * bone/node which is affected by this animation channel. The keyframes - * are given in three separate series of values, one each for position, - * rotation and scaling. The transformation matrix computed from these - * values replaces the node's original transformation matrix at a - * specific time. - * This means all keys are absolute and not relative to the bone default pose. - * The order in which the transformations are applied is - * - as usual - scaling, rotation, translation. - * - * @note All keys are returned in their correct, chronological order. - * Duplicate keys don't pass the validation step. Most likely there - * will be no negative time values, but they are not forbidden also ( so - * implementations need to cope with them! ) */ -struct aiNodeAnim { - /** The name of the node affected by this animation. The node - * must exist and it must be unique.*/ - C_STRUCT aiString mNodeName; - - /** The number of position keys */ - unsigned int mNumPositionKeys; - - /** The position keys of this animation channel. Positions are - * specified as 3D vector. The array is mNumPositionKeys in size. - * - * If there are position keys, there will also be at least one - * scaling and one rotation key.*/ - C_STRUCT aiVectorKey* mPositionKeys; - - /** The number of rotation keys */ - unsigned int mNumRotationKeys; - - /** The rotation keys of this animation channel. Rotations are - * given as quaternions, which are 4D vectors. The array is - * mNumRotationKeys in size. - * - * If there are rotation keys, there will also be at least one - * scaling and one position key. */ - C_STRUCT aiQuatKey* mRotationKeys; - - /** The number of scaling keys */ - unsigned int mNumScalingKeys; - - /** The scaling keys of this animation channel. Scalings are - * specified as 3D vector. The array is mNumScalingKeys in size. - * - * If there are scaling keys, there will also be at least one - * position and one rotation key.*/ - C_STRUCT aiVectorKey* mScalingKeys; - - /** Defines how the animation behaves before the first - * key is encountered. - * - * The default value is aiAnimBehaviour_DEFAULT (the original - * transformation matrix of the affected node is used).*/ - C_ENUM aiAnimBehaviour mPreState; - - /** Defines how the animation behaves after the last - * key was processed. - * - * The default value is aiAnimBehaviour_DEFAULT (the original - * transformation matrix of the affected node is taken).*/ - C_ENUM aiAnimBehaviour mPostState; - -#ifdef __cplusplus - aiNodeAnim() AI_NO_EXCEPT - : mNumPositionKeys( 0 ) - , mPositionKeys( nullptr ) - , mNumRotationKeys( 0 ) - , mRotationKeys( nullptr ) - , mNumScalingKeys( 0 ) - , mScalingKeys( nullptr ) - , mPreState( aiAnimBehaviour_DEFAULT ) - , mPostState( aiAnimBehaviour_DEFAULT ) { - // empty - } - - ~aiNodeAnim() { - delete [] mPositionKeys; - delete [] mRotationKeys; - delete [] mScalingKeys; - } -#endif // __cplusplus -}; - -// --------------------------------------------------------------------------- -/** Describes vertex-based animations for a single mesh or a group of - * meshes. Meshes carry the animation data for each frame in their - * aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to - * define keyframes linking each mesh attachment to a particular - * point in time. */ -struct aiMeshAnim -{ - /** Name of the mesh to be animated. An empty string is not allowed, - * animated meshes need to be named (not necessarily uniquely, - * the name can basically serve as wild-card to select a group - * of meshes with similar animation setup)*/ - C_STRUCT aiString mName; - - /** Size of the #mKeys array. Must be 1, at least. */ - unsigned int mNumKeys; - - /** Key frames of the animation. May not be NULL. */ - C_STRUCT aiMeshKey* mKeys; - -#ifdef __cplusplus - - aiMeshAnim() AI_NO_EXCEPT - : mNumKeys() - , mKeys() - {} - - ~aiMeshAnim() - { - delete[] mKeys; - } - -#endif -}; - -// --------------------------------------------------------------------------- -/** Describes a morphing animation of a given mesh. */ -struct aiMeshMorphAnim -{ - /** Name of the mesh to be animated. An empty string is not allowed, - * animated meshes need to be named (not necessarily uniquely, - * the name can basically serve as wildcard to select a group - * of meshes with similar animation setup)*/ - C_STRUCT aiString mName; - - /** Size of the #mKeys array. Must be 1, at least. */ - unsigned int mNumKeys; - - /** Key frames of the animation. May not be NULL. */ - C_STRUCT aiMeshMorphKey* mKeys; - -#ifdef __cplusplus - - aiMeshMorphAnim() AI_NO_EXCEPT - : mNumKeys() - , mKeys() - {} - - ~aiMeshMorphAnim() - { - delete[] mKeys; - } - -#endif -}; - -// --------------------------------------------------------------------------- -/** An animation consists of key-frame data for a number of nodes. For - * each node affected by the animation a separate series of data is given.*/ -struct aiAnimation { - /** The name of the animation. If the modeling package this data was - * exported from does support only a single animation channel, this - * name is usually empty (length is zero). */ - C_STRUCT aiString mName; - - /** Duration of the animation in ticks. */ - double mDuration; - - /** Ticks per second. 0 if not specified in the imported file */ - double mTicksPerSecond; - - /** The number of bone animation channels. Each channel affects - * a single node. */ - unsigned int mNumChannels; - - /** The node animation channels. Each channel affects a single node. - * The array is mNumChannels in size. */ - C_STRUCT aiNodeAnim** mChannels; - - - /** The number of mesh animation channels. Each channel affects - * a single mesh and defines vertex-based animation. */ - unsigned int mNumMeshChannels; - - /** The mesh animation channels. Each channel affects a single mesh. - * The array is mNumMeshChannels in size. */ - C_STRUCT aiMeshAnim** mMeshChannels; - - /** The number of mesh animation channels. Each channel affects - * a single mesh and defines morphing animation. */ - unsigned int mNumMorphMeshChannels; - - /** The morph mesh animation channels. Each channel affects a single mesh. - * The array is mNumMorphMeshChannels in size. */ - C_STRUCT aiMeshMorphAnim **mMorphMeshChannels; - -#ifdef __cplusplus - aiAnimation() AI_NO_EXCEPT - : mDuration(-1.) - , mTicksPerSecond(0.) - , mNumChannels(0) - , mChannels(nullptr) - , mNumMeshChannels(0) - , mMeshChannels(nullptr) - , mNumMorphMeshChannels(0) - , mMorphMeshChannels(nullptr) { - // empty - } - - ~aiAnimation() { - // DO NOT REMOVE THIS ADDITIONAL CHECK - if ( mNumChannels && mChannels ) { - for( unsigned int a = 0; a < mNumChannels; a++) { - delete mChannels[ a ]; - } - - delete [] mChannels; - } - if (mNumMeshChannels && mMeshChannels) { - for( unsigned int a = 0; a < mNumMeshChannels; a++) { - delete mMeshChannels[a]; - } - - delete [] mMeshChannels; - } - if (mNumMorphMeshChannels && mMorphMeshChannels) { - for( unsigned int a = 0; a < mNumMorphMeshChannels; a++) { - delete mMorphMeshChannels[a]; - } - - delete [] mMorphMeshChannels; - } - } -#endif // __cplusplus -}; - -#ifdef __cplusplus - -} - -/// @brief Some C++ utilities for inter- and extrapolation -namespace Assimp { - -// --------------------------------------------------------------------------- -/** - * @brief CPP-API: Utility class to simplify interpolations of various data types. - * - * The type of interpolation is chosen automatically depending on the - * types of the arguments. - */ -template <typename T> -struct Interpolator -{ - // ------------------------------------------------------------------ - /** @brief Get the result of the interpolation between a,b. - * - * The interpolation algorithm depends on the type of the operands. - * aiQuaternion's and aiQuatKey's SLERP, the rest does a simple - * linear interpolation. */ - void operator () (T& out,const T& a, const T& b, ai_real d) const { - out = a + (b-a)*d; - } -}; // ! Interpolator <T> - -//! @cond Never - -template <> -struct Interpolator <aiQuaternion> { - void operator () (aiQuaternion& out,const aiQuaternion& a, - const aiQuaternion& b, ai_real d) const - { - aiQuaternion::Interpolate(out,a,b,d); - } -}; // ! Interpolator <aiQuaternion> - -template <> -struct Interpolator <unsigned int> { - void operator () (unsigned int& out,unsigned int a, - unsigned int b, ai_real d) const - { - out = d>0.5f ? b : a; - } -}; // ! Interpolator <aiQuaternion> - -template <> -struct Interpolator<aiVectorKey> { - void operator () (aiVector3D& out,const aiVectorKey& a, - const aiVectorKey& b, ai_real d) const - { - Interpolator<aiVector3D> ipl; - ipl(out,a.mValue,b.mValue,d); - } -}; // ! Interpolator <aiVectorKey> - -template <> -struct Interpolator<aiQuatKey> { - void operator () (aiQuaternion& out, const aiQuatKey& a, - const aiQuatKey& b, ai_real d) const - { - Interpolator<aiQuaternion> ipl; - ipl(out,a.mValue,b.mValue,d); - } -}; // ! Interpolator <aiQuatKey> - -template <> -struct Interpolator<aiMeshKey> { - void operator () (unsigned int& out, const aiMeshKey& a, - const aiMeshKey& b, ai_real d) const - { - Interpolator<unsigned int> ipl; - ipl(out,a.mValue,b.mValue,d); - } -}; // ! Interpolator <aiQuatKey> - -//! @endcond - -} // ! end namespace Assimp - -#endif // __cplusplus - -#endif // AI_ANIM_H_INC diff --git a/thirdparty/assimp/include/assimp/camera.h b/thirdparty/assimp/include/assimp/camera.h deleted file mode 100644 index adb749ff59..0000000000 --- a/thirdparty/assimp/include/assimp/camera.h +++ /dev/null @@ -1,225 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file camera.h - * @brief Defines the aiCamera data structure - */ - -#pragma once -#ifndef AI_CAMERA_H_INC -#define AI_CAMERA_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include "types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------------- -/** Helper structure to describe a virtual camera. - * - * Cameras have a representation in the node graph and can be animated. - * An important aspect is that the camera itself is also part of the - * scene-graph. This means, any values such as the look-at vector are not - * *absolute*, they're <b>relative</b> to the coordinate system defined - * by the node which corresponds to the camera. This allows for camera - * animations. For static cameras parameters like the 'look-at' or 'up' vectors - * are usually specified directly in aiCamera, but beware, they could also - * be encoded in the node transformation. The following (pseudo)code sample - * shows how to do it: <br><br> - * @code - * // Get the camera matrix for a camera at a specific time - * // if the node hierarchy for the camera does not contain - * // at least one animated node this is a static computation - * get-camera-matrix (node sceneRoot, camera cam) : matrix - * { - * node cnd = find-node-for-camera(cam) - * matrix cmt = identity() - * - * // as usual - get the absolute camera transformation for this frame - * for each node nd in hierarchy from sceneRoot to cnd - * matrix cur - * if (is-animated(nd)) - * cur = eval-animation(nd) - * else cur = nd->mTransformation; - * cmt = mult-matrices( cmt, cur ) - * end for - * - * // now multiply with the camera's own local transform - * cam = mult-matrices (cam, get-camera-matrix(cmt) ) - * } - * @endcode - * - * @note some file formats (such as 3DS, ASE) export a "target point" - - * the point the camera is looking at (it can even be animated). Assimp - * writes the target point as a subnode of the camera's main node, - * called "<camName>.Target". However this is just additional information - * then the transformation tracks of the camera main node make the - * camera already look in the right direction. - * -*/ -struct aiCamera -{ - /** The name of the camera. - * - * There must be a node in the scenegraph with the same name. - * This node specifies the position of the camera in the scene - * hierarchy and can be animated. - */ - C_STRUCT aiString mName; - - /** Position of the camera relative to the coordinate space - * defined by the corresponding node. - * - * The default value is 0|0|0. - */ - C_STRUCT aiVector3D mPosition; - - /** 'Up' - vector of the camera coordinate system relative to - * the coordinate space defined by the corresponding node. - * - * The 'right' vector of the camera coordinate system is - * the cross product of the up and lookAt vectors. - * The default value is 0|1|0. The vector - * may be normalized, but it needn't. - */ - C_STRUCT aiVector3D mUp; - - - /** 'LookAt' - vector of the camera coordinate system relative to - * the coordinate space defined by the corresponding node. - * - * This is the viewing direction of the user. - * The default value is 0|0|1. The vector - * may be normalized, but it needn't. - */ - C_STRUCT aiVector3D mLookAt; - - /** Half horizontal field of view angle, in radians. - * - * The field of view angle is the angle between the center - * line of the screen and the left or right border. - * The default value is 1/4PI. - */ - float mHorizontalFOV; - - /** Distance of the near clipping plane from the camera. - * - * The value may not be 0.f (for arithmetic reasons to prevent - * a division through zero). The default value is 0.1f. - */ - float mClipPlaneNear; - - /** Distance of the far clipping plane from the camera. - * - * The far clipping plane must, of course, be further away than the - * near clipping plane. The default value is 1000.f. The ratio - * between the near and the far plane should not be too - * large (between 1000-10000 should be ok) to avoid floating-point - * inaccuracies which could lead to z-fighting. - */ - float mClipPlaneFar; - - /** Screen aspect ratio. - * - * This is the ration between the width and the height of the - * screen. Typical values are 4/3, 1/2 or 1/1. This value is - * 0 if the aspect ratio is not defined in the source file. - * 0 is also the default value. - */ - float mAspect; - -#ifdef __cplusplus - - aiCamera() AI_NO_EXCEPT - : mUp (0.f,1.f,0.f) - , mLookAt (0.f,0.f,1.f) - , mHorizontalFOV (0.25f * (float)AI_MATH_PI) - , mClipPlaneNear (0.1f) - , mClipPlaneFar (1000.f) - , mAspect (0.f) - {} - - /** @brief Get a *right-handed* camera matrix from me - * @param out Camera matrix to be filled - */ - void GetCameraMatrix (aiMatrix4x4& out) const - { - /** todo: test ... should work, but i'm not absolutely sure */ - - /** We don't know whether these vectors are already normalized ...*/ - aiVector3D zaxis = mLookAt; zaxis.Normalize(); - aiVector3D yaxis = mUp; yaxis.Normalize(); - aiVector3D xaxis = mUp^mLookAt; xaxis.Normalize(); - - out.a4 = -(xaxis * mPosition); - out.b4 = -(yaxis * mPosition); - out.c4 = -(zaxis * mPosition); - - out.a1 = xaxis.x; - out.a2 = xaxis.y; - out.a3 = xaxis.z; - - out.b1 = yaxis.x; - out.b2 = yaxis.y; - out.b3 = yaxis.z; - - out.c1 = zaxis.x; - out.c2 = zaxis.y; - out.c3 = zaxis.z; - - out.d1 = out.d2 = out.d3 = 0.f; - out.d4 = 1.f; - } - -#endif -}; - - -#ifdef __cplusplus -} -#endif - -#endif // AI_CAMERA_H_INC diff --git a/thirdparty/assimp/include/assimp/cexport.h b/thirdparty/assimp/include/assimp/cexport.h deleted file mode 100644 index cbc0253d50..0000000000 --- a/thirdparty/assimp/include/assimp/cexport.h +++ /dev/null @@ -1,265 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file cexport.h -* @brief Defines the C-API for the Assimp export interface -*/ -#pragma once -#ifndef AI_EXPORT_H_INC -#define AI_EXPORT_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifndef ASSIMP_BUILD_NO_EXPORT - -// Public ASSIMP data structures -#include <assimp/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct aiScene; // aiScene.h -struct aiFileIO; // aiFileIO.h - -// -------------------------------------------------------------------------------- -/** Describes an file format which Assimp can export to. Use #aiGetExportFormatCount() to -* learn how many export formats the current Assimp build supports and #aiGetExportFormatDescription() -* to retrieve a description of an export format option. -*/ -struct aiExportFormatDesc -{ - /// a short string ID to uniquely identify the export format. Use this ID string to - /// specify which file format you want to export to when calling #aiExportScene(). - /// Example: "dae" or "obj" - const char* id; - - /// A short description of the file format to present to users. Useful if you want - /// to allow the user to select an export format. - const char* description; - - /// Recommended file extension for the exported file in lower case. - const char* fileExtension; -}; - - -// -------------------------------------------------------------------------------- -/** Returns the number of export file formats available in the current Assimp build. - * Use aiGetExportFormatDescription() to retrieve infos of a specific export format. - */ -ASSIMP_API size_t aiGetExportFormatCount(void); - -// -------------------------------------------------------------------------------- -/** Returns a description of the nth export file format. Use #aiGetExportFormatCount() - * to learn how many export formats are supported. The description must be released by - * calling aiReleaseExportFormatDescription afterwards. - * @param pIndex Index of the export format to retrieve information for. Valid range is - * 0 to #aiGetExportFormatCount() - * @return A description of that specific export format. NULL if pIndex is out of range. - */ -ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex); - -// -------------------------------------------------------------------------------- -/** Release a description of the nth export file format. Must be returned by -* aiGetExportFormatDescription -* @param desc Pointer to the description -*/ -ASSIMP_API void aiReleaseExportFormatDescription( const C_STRUCT aiExportFormatDesc *desc ); - -// -------------------------------------------------------------------------------- -/** Create a modifiable copy of a scene. - * This is useful to import files via Assimp, change their topology and - * export them again. Since the scene returned by the various importer functions - * is const, a modifiable copy is needed. - * @param pIn Valid scene to be copied - * @param pOut Receives a modifyable copy of the scene. Use aiFreeScene() to - * delete it again. - */ -ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn, - C_STRUCT aiScene** pOut); - - -// -------------------------------------------------------------------------------- -/** Frees a scene copy created using aiCopyScene() */ -ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn); - -// -------------------------------------------------------------------------------- -/** Exports the given scene to a chosen file format and writes the result file(s) to disk. -* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function. -* The scene is expected to conform to Assimp's Importer output format as specified -* in the @link data Data Structures Page @endlink. In short, this means the model data -* should use a right-handed coordinate systems, face winding should be counter-clockwise -* and the UV coordinate origin is assumed to be in the upper left. If your input data -* uses different conventions, have a look at the last parameter. -* @param pFormatId ID string to specify to which format you want to export to. Use -* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available. -* @param pFileName Output file to write -* @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated -* flags, but in reality only a subset of them makes sense here. Specifying -* 'preprocessing' flags is useful if the input scene does not conform to -* Assimp's default conventions as specified in the @link data Data Structures Page @endlink. -* In short, this means the geometry data should use a right-handed coordinate systems, face -* winding should be counter-clockwise and the UV coordinate origin is assumed to be in -* the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and -* #aiProcess_FlipWindingOrder flags are used in the import side to allow users -* to have those defaults automatically adapted to their conventions. Specifying those flags -* for exporting has the opposite effect, respectively. Some other of the -* #aiPostProcessSteps enumerated values may be useful as well, but you'll need -* to try out what their effect on the exported file is. Many formats impose -* their own restrictions on the structure of the geometry stored therein, -* so some preprocessing may have little or no effect at all, or may be -* redundant as exporters would apply them anyhow. A good example -* is triangulation - whilst you can enforce it by specifying -* the #aiProcess_Triangulate flag, most export formats support only -* triangulate data so they would run the step anyway. -* -* If assimp detects that the input scene was directly taken from the importer side of -* the library (i.e. not copied using aiCopyScene and potetially modified afterwards), -* any postprocessing steps already applied to the scene will not be applied again, unless -* they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and -* #aiProcess_FlipWindingOrder). -* @return a status code indicating the result of the export -* @note Use aiCopyScene() to get a modifiable copy of a previously -* imported scene. -*/ -ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene, - const char* pFormatId, - const char* pFileName, - unsigned int pPreprocessing); - - -// -------------------------------------------------------------------------------- -/** Exports the given scene to a chosen file format using custom IO logic supplied by you. -* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function. -* @param pFormatId ID string to specify to which format you want to export to. Use -* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available. -* @param pFileName Output file to write -* @param pIO custom IO implementation to be used. Use this if you use your own storage methods. -* If none is supplied, a default implementation using standard file IO is used. Note that -* #aiExportSceneToBlob is provided as convenience function to export to memory buffers. -* @param pPreprocessing Please see the documentation for #aiExportScene -* @return a status code indicating the result of the export -* @note Include <aiFileIO.h> for the definition of #aiFileIO. -* @note Use aiCopyScene() to get a modifiable copy of a previously -* imported scene. -*/ -ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene, - const char* pFormatId, - const char* pFileName, - C_STRUCT aiFileIO* pIO, - unsigned int pPreprocessing ); - -// -------------------------------------------------------------------------------- -/** Describes a blob of exported scene data. Use #aiExportSceneToBlob() to create a blob containing an -* exported scene. The memory referred by this structure is owned by Assimp. -* to free its resources. Don't try to free the memory on your side - it will crash for most build configurations -* due to conflicting heaps. -* -* Blobs can be nested - each blob may reference another blob, which may in turn reference another blob and so on. -* This is used when exporters write more than one output file for a given #aiScene. See the remarks for -* #aiExportDataBlob::name for more information. -*/ -struct aiExportDataBlob -{ - /// Size of the data in bytes - size_t size; - - /// The data. - void* data; - - /** Name of the blob. An empty string always - indicates the first (and primary) blob, - which contains the actual file data. - Any other blobs are auxiliary files produced - by exporters (i.e. material files). Existence - of such files depends on the file format. Most - formats don't split assets across multiple files. - - If used, blob names usually contain the file - extension that should be used when writing - the data to disc. - */ - C_STRUCT aiString name; - - /** Pointer to the next blob in the chain or NULL if there is none. */ - C_STRUCT aiExportDataBlob * next; - -#ifdef __cplusplus - /// Default constructor - aiExportDataBlob() { size = 0; data = next = NULL; } - /// Releases the data - ~aiExportDataBlob() { delete [] static_cast<unsigned char*>( data ); delete next; } - -private: - // no copying - aiExportDataBlob(const aiExportDataBlob& ); - aiExportDataBlob& operator= (const aiExportDataBlob& ); -#endif // __cplusplus -}; - -// -------------------------------------------------------------------------------- -/** Exports the given scene to a chosen file format. Returns the exported data as a binary blob which -* you can write into a file or something. When you're done with the data, use #aiReleaseExportBlob() -* to free the resources associated with the export. -* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function. -* @param pFormatId ID string to specify to which format you want to export to. Use -* #aiGetExportFormatCount() / #aiGetExportFormatDescription() to learn which export formats are available. -* @param pPreprocessing Please see the documentation for #aiExportScene -* @return the exported data or NULL in case of error -*/ -ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId, - unsigned int pPreprocessing ); - -// -------------------------------------------------------------------------------- -/** Releases the memory associated with the given exported data. Use this function to free a data blob -* returned by aiExportScene(). -* @param pData the data blob returned by #aiExportSceneToBlob -*/ -ASSIMP_API void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData ); - -#ifdef __cplusplus -} -#endif - -#endif // ASSIMP_BUILD_NO_EXPORT -#endif // AI_EXPORT_H_INC diff --git a/thirdparty/assimp/include/assimp/cfileio.h b/thirdparty/assimp/include/assimp/cfileio.h deleted file mode 100644 index be90999d87..0000000000 --- a/thirdparty/assimp/include/assimp/cfileio.h +++ /dev/null @@ -1,144 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file cfileio.h - * @brief Defines generic C routines to access memory-mapped files - */ -#pragma once -#ifndef AI_FILEIO_H_INC -#define AI_FILEIO_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct aiFileIO; -struct aiFile; - -// aiFile callbacks -typedef size_t (*aiFileWriteProc) (C_STRUCT aiFile*, const char*, size_t, size_t); -typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t); -typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*); -typedef void (*aiFileFlushProc) (C_STRUCT aiFile*); -typedef C_ENUM aiReturn (*aiFileSeek) (C_STRUCT aiFile*, size_t, C_ENUM aiOrigin); - -// aiFileIO callbacks -typedef C_STRUCT aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*); -typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*); - -// Represents user-defined data -typedef char* aiUserData; - -// ---------------------------------------------------------------------------------- -/** @brief C-API: File system callbacks - * - * Provided are functions to open and close files. Supply a custom structure to - * the import function. If you don't, a default implementation is used. Use custom - * file systems to enable reading from other sources, such as ZIPs - * or memory locations. */ -struct aiFileIO -{ - /** Function used to open a new file - */ - aiFileOpenProc OpenProc; - - /** Function used to close an existing file - */ - aiFileCloseProc CloseProc; - - /** User-defined, opaque data */ - aiUserData UserData; -}; - -// ---------------------------------------------------------------------------------- -/** @brief C-API: File callbacks - * - * Actually, it's a data structure to wrap a set of fXXXX (e.g fopen) - * replacement functions. - * - * The default implementation of the functions utilizes the fXXX functions from - * the CRT. However, you can supply a custom implementation to Assimp by - * delivering a custom aiFileIO. Use this to enable reading from other sources, - * such as ZIP archives or memory locations. */ -struct aiFile -{ - /** Callback to read from a file */ - aiFileReadProc ReadProc; - - /** Callback to write to a file */ - aiFileWriteProc WriteProc; - - /** Callback to retrieve the current position of - * the file cursor (ftell()) - */ - aiFileTellProc TellProc; - - /** Callback to retrieve the size of the file, - * in bytes - */ - aiFileTellProc FileSizeProc; - - /** Callback to set the current position - * of the file cursor (fseek()) - */ - aiFileSeek SeekProc; - - /** Callback to flush the file contents - */ - aiFileFlushProc FlushProc; - - /** User-defined, opaque data - */ - aiUserData UserData; -}; - -#ifdef __cplusplus -} -#endif -#endif // AI_FILEIO_H_INC diff --git a/thirdparty/assimp/include/assimp/cimport.h b/thirdparty/assimp/include/assimp/cimport.h deleted file mode 100644 index 66b1c9a174..0000000000 --- a/thirdparty/assimp/include/assimp/cimport.h +++ /dev/null @@ -1,569 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file cimport.h - * @brief Defines the C-API to the Open Asset Import Library. - */ -#pragma once -#ifndef AI_ASSIMP_H_INC -#define AI_ASSIMP_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> -#include <assimp/importerdesc.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct aiScene; // aiScene.h -struct aiFileIO; // aiFileIO.h -typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */); - -// -------------------------------------------------------------------------------- -/** C-API: Represents a log stream. A log stream receives all log messages and - * streams them _somewhere_. - * @see aiGetPredefinedLogStream - * @see aiAttachLogStream - * @see aiDetachLogStream */ -// -------------------------------------------------------------------------------- -struct aiLogStream -{ - /** callback to be called */ - aiLogStreamCallback callback; - - /** user data to be passed to the callback */ - char* user; -}; - - -// -------------------------------------------------------------------------------- -/** C-API: Represents an opaque set of settings to be used during importing. - * @see aiCreatePropertyStore - * @see aiReleasePropertyStore - * @see aiImportFileExWithProperties - * @see aiSetPropertyInteger - * @see aiSetPropertyFloat - * @see aiSetPropertyString - * @see aiSetPropertyMatrix - */ -// -------------------------------------------------------------------------------- -struct aiPropertyStore { char sentinel; }; - -/** Our own C boolean type */ -typedef int aiBool; - -#define AI_FALSE 0 -#define AI_TRUE 1 - -// -------------------------------------------------------------------------------- -/** Reads the given file and returns its content. - * - * If the call succeeds, the imported data is returned in an aiScene structure. - * The data is intended to be read-only, it stays property of the ASSIMP - * library and will be stable until aiReleaseImport() is called. After you're - * done with it, call aiReleaseImport() to free the resources associated with - * this file. If the import fails, NULL is returned instead. Call - * aiGetErrorString() to retrieve a human-readable error text. - * @param pFile Path and filename of the file to be imported, - * expected to be a null-terminated c-string. NULL is not a valid value. - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. - * @return Pointer to the imported data or NULL if the import failed. - */ -ASSIMP_API const C_STRUCT aiScene* aiImportFile( - const char* pFile, - unsigned int pFlags); - -// -------------------------------------------------------------------------------- -/** Reads the given file using user-defined I/O functions and returns - * its content. - * - * If the call succeeds, the imported data is returned in an aiScene structure. - * The data is intended to be read-only, it stays property of the ASSIMP - * library and will be stable until aiReleaseImport() is called. After you're - * done with it, call aiReleaseImport() to free the resources associated with - * this file. If the import fails, NULL is returned instead. Call - * aiGetErrorString() to retrieve a human-readable error text. - * @param pFile Path and filename of the file to be imported, - * expected to be a null-terminated c-string. NULL is not a valid value. - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. - * @param pFS aiFileIO structure. Will be used to open the model file itself - * and any other files the loader needs to open. Pass NULL to use the default - * implementation. - * @return Pointer to the imported data or NULL if the import failed. - * @note Include <aiFileIO.h> for the definition of #aiFileIO. - */ -ASSIMP_API const C_STRUCT aiScene* aiImportFileEx( - const char* pFile, - unsigned int pFlags, - C_STRUCT aiFileIO* pFS); - -// -------------------------------------------------------------------------------- -/** Same as #aiImportFileEx, but adds an extra parameter containing importer settings. - * - * @param pFile Path and filename of the file to be imported, - * expected to be a null-terminated c-string. NULL is not a valid value. - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. - * @param pFS aiFileIO structure. Will be used to open the model file itself - * and any other files the loader needs to open. Pass NULL to use the default - * implementation. - * @param pProps #aiPropertyStore instance containing import settings. - * @return Pointer to the imported data or NULL if the import failed. - * @note Include <aiFileIO.h> for the definition of #aiFileIO. - * @see aiImportFileEx - */ -ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties( - const char* pFile, - unsigned int pFlags, - C_STRUCT aiFileIO* pFS, - const C_STRUCT aiPropertyStore* pProps); - -// -------------------------------------------------------------------------------- -/** Reads the given file from a given memory buffer, - * - * If the call succeeds, the contents of the file are returned as a pointer to an - * aiScene object. The returned data is intended to be read-only, the importer keeps - * ownership of the data and will destroy it upon destruction. If the import fails, - * NULL is returned. - * A human-readable error description can be retrieved by calling aiGetErrorString(). - * @param pBuffer Pointer to the file data - * @param pLength Length of pBuffer, in bytes - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. If you wish to inspect the imported - * scene first in order to fine-tune your post-processing setup, - * consider to use #aiApplyPostProcessing(). - * @param pHint An additional hint to the library. If this is a non empty string, - * the library looks for a loader to support the file extension specified by pHint - * and passes the file to the first matching loader. If this loader is unable to - * completely the request, the library continues and tries to determine the file - * format on its own, a task that may or may not be successful. - * Check the return value, and you'll know ... - * @return A pointer to the imported data, NULL if the import failed. - * - * @note This is a straightforward way to decode models from memory - * buffers, but it doesn't handle model formats that spread their - * data across multiple files or even directories. Examples include - * OBJ or MD3, which outsource parts of their material info into - * external scripts. If you need full functionality, provide - * a custom IOSystem to make Assimp find these files and use - * the regular aiImportFileEx()/aiImportFileExWithProperties() API. - */ -ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory( - const char* pBuffer, - unsigned int pLength, - unsigned int pFlags, - const char* pHint); - -// -------------------------------------------------------------------------------- -/** Same as #aiImportFileFromMemory, but adds an extra parameter containing importer settings. - * - * @param pBuffer Pointer to the file data - * @param pLength Length of pBuffer, in bytes - * @param pFlags Optional post processing steps to be executed after - * a successful import. Provide a bitwise combination of the - * #aiPostProcessSteps flags. If you wish to inspect the imported - * scene first in order to fine-tune your post-processing setup, - * consider to use #aiApplyPostProcessing(). - * @param pHint An additional hint to the library. If this is a non empty string, - * the library looks for a loader to support the file extension specified by pHint - * and passes the file to the first matching loader. If this loader is unable to - * completely the request, the library continues and tries to determine the file - * format on its own, a task that may or may not be successful. - * Check the return value, and you'll know ... - * @param pProps #aiPropertyStore instance containing import settings. - * @return A pointer to the imported data, NULL if the import failed. - * - * @note This is a straightforward way to decode models from memory - * buffers, but it doesn't handle model formats that spread their - * data across multiple files or even directories. Examples include - * OBJ or MD3, which outsource parts of their material info into - * external scripts. If you need full functionality, provide - * a custom IOSystem to make Assimp find these files and use - * the regular aiImportFileEx()/aiImportFileExWithProperties() API. - * @see aiImportFileFromMemory - */ -ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemoryWithProperties( - const char* pBuffer, - unsigned int pLength, - unsigned int pFlags, - const char* pHint, - const C_STRUCT aiPropertyStore* pProps); - -// -------------------------------------------------------------------------------- -/** Apply post-processing to an already-imported scene. - * - * This is strictly equivalent to calling #aiImportFile()/#aiImportFileEx with the - * same flags. However, you can use this separate function to inspect the imported - * scene first to fine-tune your post-processing setup. - * @param pScene Scene to work on. - * @param pFlags Provide a bitwise combination of the #aiPostProcessSteps flags. - * @return A pointer to the post-processed data. Post processing is done in-place, - * meaning this is still the same #aiScene which you passed for pScene. However, - * _if_ post-processing failed, the scene could now be NULL. That's quite a rare - * case, post processing steps are not really designed to 'fail'. To be exact, - * the #aiProcess_ValidateDataStructure flag is currently the only post processing step - * which can actually cause the scene to be reset to NULL. - */ -ASSIMP_API const C_STRUCT aiScene* aiApplyPostProcessing( - const C_STRUCT aiScene* pScene, - unsigned int pFlags); - -// -------------------------------------------------------------------------------- -/** Get one of the predefine log streams. This is the quick'n'easy solution to - * access Assimp's log system. Attaching a log stream can slightly reduce Assimp's - * overall import performance. - * - * Usage is rather simple (this will stream the log to a file, named log.txt, and - * the stdout stream of the process: - * @code - * struct aiLogStream c; - * c = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"log.txt"); - * aiAttachLogStream(&c); - * c = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL); - * aiAttachLogStream(&c); - * @endcode - * - * @param pStreams One of the #aiDefaultLogStream enumerated values. - * @param file Solely for the #aiDefaultLogStream_FILE flag: specifies the file to write to. - * Pass NULL for all other flags. - * @return The log stream. callback is set to NULL if something went wrong. - */ -ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream( - C_ENUM aiDefaultLogStream pStreams, - const char* file); - -// -------------------------------------------------------------------------------- -/** Attach a custom log stream to the libraries' logging system. - * - * Attaching a log stream can slightly reduce Assimp's overall import - * performance. Multiple log-streams can be attached. - * @param stream Describes the new log stream. - * @note To ensure proper destruction of the logging system, you need to manually - * call aiDetachLogStream() on every single log stream you attach. - * Alternatively (for the lazy folks) #aiDetachAllLogStreams is provided. - */ -ASSIMP_API void aiAttachLogStream( - const C_STRUCT aiLogStream* stream); - -// -------------------------------------------------------------------------------- -/** Enable verbose logging. Verbose logging includes debug-related stuff and - * detailed import statistics. This can have severe impact on import performance - * and memory consumption. However, it might be useful to find out why a file - * didn't read correctly. - * @param d AI_TRUE or AI_FALSE, your decision. - */ -ASSIMP_API void aiEnableVerboseLogging(aiBool d); - -// -------------------------------------------------------------------------------- -/** Detach a custom log stream from the libraries' logging system. - * - * This is the counterpart of #aiAttachLogStream. If you attached a stream, - * don't forget to detach it again. - * @param stream The log stream to be detached. - * @return AI_SUCCESS if the log stream has been detached successfully. - * @see aiDetachAllLogStreams - */ -ASSIMP_API C_ENUM aiReturn aiDetachLogStream( - const C_STRUCT aiLogStream* stream); - -// -------------------------------------------------------------------------------- -/** Detach all active log streams from the libraries' logging system. - * This ensures that the logging system is terminated properly and all - * resources allocated by it are actually freed. If you attached a stream, - * don't forget to detach it again. - * @see aiAttachLogStream - * @see aiDetachLogStream - */ -ASSIMP_API void aiDetachAllLogStreams(void); - -// -------------------------------------------------------------------------------- -/** Releases all resources associated with the given import process. - * - * Call this function after you're done with the imported data. - * @param pScene The imported data to release. NULL is a valid value. - */ -ASSIMP_API void aiReleaseImport( - const C_STRUCT aiScene* pScene); - -// -------------------------------------------------------------------------------- -/** Returns the error text of the last failed import process. - * - * @return A textual description of the error that occurred at the last - * import process. NULL if there was no error. There can't be an error if you - * got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing. - */ -ASSIMP_API const char* aiGetErrorString(void); - -// -------------------------------------------------------------------------------- -/** Returns whether a given file extension is supported by ASSIMP - * - * @param szExtension Extension for which the function queries support for. - * Must include a leading dot '.'. Example: ".3ds", ".md3" - * @return AI_TRUE if the file extension is supported. - */ -ASSIMP_API aiBool aiIsExtensionSupported( - const char* szExtension); - -// -------------------------------------------------------------------------------- -/** Get a list of all file extensions supported by ASSIMP. - * - * If a file extension is contained in the list this does, of course, not - * mean that ASSIMP is able to load all files with this extension. - * @param szOut String to receive the extension list. - * Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter. - */ -ASSIMP_API void aiGetExtensionList( - C_STRUCT aiString* szOut); - -// -------------------------------------------------------------------------------- -/** Get the approximated storage required by an imported asset - * @param pIn Input asset. - * @param in Data structure to be filled. - */ -ASSIMP_API void aiGetMemoryRequirements( - const C_STRUCT aiScene* pIn, - C_STRUCT aiMemoryInfo* in); - - - -// -------------------------------------------------------------------------------- -/** Create an empty property store. Property stores are used to collect import - * settings. - * @return New property store. Property stores need to be manually destroyed using - * the #aiReleasePropertyStore API function. - */ -ASSIMP_API C_STRUCT aiPropertyStore* aiCreatePropertyStore(void); - -// -------------------------------------------------------------------------------- -/** Delete a property store. - * @param p Property store to be deleted. - */ -ASSIMP_API void aiReleasePropertyStore(C_STRUCT aiPropertyStore* p); - -// -------------------------------------------------------------------------------- -/** Set an integer property. - * - * This is the C-version of #Assimp::Importer::SetPropertyInteger(). In the C - * interface, properties are always shared by all imports. It is not possible to - * specify them per import. - * - * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store. - * @param szName Name of the configuration property to be set. All supported - * public properties are defined in the config.h header file (AI_CONFIG_XXX). - * @param value New value for the property - */ -ASSIMP_API void aiSetImportPropertyInteger( - C_STRUCT aiPropertyStore* store, - const char* szName, - int value); - -// -------------------------------------------------------------------------------- -/** Set a floating-point property. - * - * This is the C-version of #Assimp::Importer::SetPropertyFloat(). In the C - * interface, properties are always shared by all imports. It is not possible to - * specify them per import. - * - * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store. - * @param szName Name of the configuration property to be set. All supported - * public properties are defined in the config.h header file (AI_CONFIG_XXX). - * @param value New value for the property - */ -ASSIMP_API void aiSetImportPropertyFloat( - C_STRUCT aiPropertyStore* store, - const char* szName, - ai_real value); - -// -------------------------------------------------------------------------------- -/** Set a string property. - * - * This is the C-version of #Assimp::Importer::SetPropertyString(). In the C - * interface, properties are always shared by all imports. It is not possible to - * specify them per import. - * - * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store. - * @param szName Name of the configuration property to be set. All supported - * public properties are defined in the config.h header file (AI_CONFIG_XXX). - * @param st New value for the property - */ -ASSIMP_API void aiSetImportPropertyString( - C_STRUCT aiPropertyStore* store, - const char* szName, - const C_STRUCT aiString* st); - -// -------------------------------------------------------------------------------- -/** Set a matrix property. - * - * This is the C-version of #Assimp::Importer::SetPropertyMatrix(). In the C - * interface, properties are always shared by all imports. It is not possible to - * specify them per import. - * - * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store. - * @param szName Name of the configuration property to be set. All supported - * public properties are defined in the config.h header file (AI_CONFIG_XXX). - * @param mat New value for the property - */ -ASSIMP_API void aiSetImportPropertyMatrix( - C_STRUCT aiPropertyStore* store, - const char* szName, - const C_STRUCT aiMatrix4x4* mat); - -// -------------------------------------------------------------------------------- -/** Construct a quaternion from a 3x3 rotation matrix. - * @param quat Receives the output quaternion. - * @param mat Matrix to 'quaternionize'. - * @see aiQuaternion(const aiMatrix3x3& pRotMatrix) - */ -ASSIMP_API void aiCreateQuaternionFromMatrix( - C_STRUCT aiQuaternion* quat, - const C_STRUCT aiMatrix3x3* mat); - -// -------------------------------------------------------------------------------- -/** Decompose a transformation matrix into its rotational, translational and - * scaling components. - * - * @param mat Matrix to decompose - * @param scaling Receives the scaling component - * @param rotation Receives the rotational component - * @param position Receives the translational component. - * @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const; - */ -ASSIMP_API void aiDecomposeMatrix( - const C_STRUCT aiMatrix4x4* mat, - C_STRUCT aiVector3D* scaling, - C_STRUCT aiQuaternion* rotation, - C_STRUCT aiVector3D* position); - -// -------------------------------------------------------------------------------- -/** Transpose a 4x4 matrix. - * @param mat Pointer to the matrix to be transposed - */ -ASSIMP_API void aiTransposeMatrix4( - C_STRUCT aiMatrix4x4* mat); - -// -------------------------------------------------------------------------------- -/** Transpose a 3x3 matrix. - * @param mat Pointer to the matrix to be transposed - */ -ASSIMP_API void aiTransposeMatrix3( - C_STRUCT aiMatrix3x3* mat); - -// -------------------------------------------------------------------------------- -/** Transform a vector by a 3x3 matrix - * @param vec Vector to be transformed. - * @param mat Matrix to transform the vector with. - */ -ASSIMP_API void aiTransformVecByMatrix3( - C_STRUCT aiVector3D* vec, - const C_STRUCT aiMatrix3x3* mat); - -// -------------------------------------------------------------------------------- -/** Transform a vector by a 4x4 matrix - * @param vec Vector to be transformed. - * @param mat Matrix to transform the vector with. - */ -ASSIMP_API void aiTransformVecByMatrix4( - C_STRUCT aiVector3D* vec, - const C_STRUCT aiMatrix4x4* mat); - -// -------------------------------------------------------------------------------- -/** Multiply two 4x4 matrices. - * @param dst First factor, receives result. - * @param src Matrix to be multiplied with 'dst'. - */ -ASSIMP_API void aiMultiplyMatrix4( - C_STRUCT aiMatrix4x4* dst, - const C_STRUCT aiMatrix4x4* src); - -// -------------------------------------------------------------------------------- -/** Multiply two 3x3 matrices. - * @param dst First factor, receives result. - * @param src Matrix to be multiplied with 'dst'. - */ -ASSIMP_API void aiMultiplyMatrix3( - C_STRUCT aiMatrix3x3* dst, - const C_STRUCT aiMatrix3x3* src); - -// -------------------------------------------------------------------------------- -/** Get a 3x3 identity matrix. - * @param mat Matrix to receive its personal identity - */ -ASSIMP_API void aiIdentityMatrix3( - C_STRUCT aiMatrix3x3* mat); - -// -------------------------------------------------------------------------------- -/** Get a 4x4 identity matrix. - * @param mat Matrix to receive its personal identity - */ -ASSIMP_API void aiIdentityMatrix4( - C_STRUCT aiMatrix4x4* mat); - -// -------------------------------------------------------------------------------- -/** Returns the number of import file formats available in the current Assimp build. - * Use aiGetImportFormatDescription() to retrieve infos of a specific import format. - */ -ASSIMP_API size_t aiGetImportFormatCount(void); - -// -------------------------------------------------------------------------------- -/** Returns a description of the nth import file format. Use #aiGetImportFormatCount() - * to learn how many import formats are supported. - * @param pIndex Index of the import format to retrieve information for. Valid range is - * 0 to #aiGetImportFormatCount() - * @return A description of that specific import format. NULL if pIndex is out of range. - */ -ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImportFormatDescription( size_t pIndex); -#ifdef __cplusplus -} -#endif - -#endif // AI_ASSIMP_H_INC diff --git a/thirdparty/assimp/include/assimp/color4.h b/thirdparty/assimp/include/assimp/color4.h deleted file mode 100644 index fa86128f4f..0000000000 --- a/thirdparty/assimp/include/assimp/color4.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file color4.h - * @brief RGBA color structure, including operators when compiling in C++ - */ -#pragma once -#ifndef AI_COLOR4D_H_INC -#define AI_COLOR4D_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/defs.h> - -#ifdef __cplusplus - -// ---------------------------------------------------------------------------------- -/** Represents a color in Red-Green-Blue space including an -* alpha component. Color values range from 0 to 1. */ -// ---------------------------------------------------------------------------------- -template <typename TReal> -class aiColor4t { -public: - aiColor4t() AI_NO_EXCEPT : r(), g(), b(), a() {} - aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a) - : r(_r), g(_g), b(_b), a(_a) {} - explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {} - aiColor4t (const aiColor4t& o) = default; - - // combined operators - const aiColor4t& operator += (const aiColor4t& o); - const aiColor4t& operator -= (const aiColor4t& o); - const aiColor4t& operator *= (TReal f); - const aiColor4t& operator /= (TReal f); - - // comparison - bool operator == (const aiColor4t& other) const; - bool operator != (const aiColor4t& other) const; - bool operator < (const aiColor4t& other) const; - - // color tuple access, rgba order - inline TReal operator[](unsigned int i) const; - inline TReal& operator[](unsigned int i); - - /** check whether a color is (close to) black */ - inline bool IsBlack() const; - - // Red, green, blue and alpha color values - TReal r, g, b, a; -}; // !struct aiColor4D - -typedef aiColor4t<ai_real> aiColor4D; - -#else - -struct aiColor4D { - ai_real r, g, b, a; -}; - -#endif // __cplusplus - -#endif // AI_COLOR4D_H_INC diff --git a/thirdparty/assimp/include/assimp/color4.inl b/thirdparty/assimp/include/assimp/color4.inl deleted file mode 100644 index d4a2a98109..0000000000 --- a/thirdparty/assimp/include/assimp/color4.inl +++ /dev/null @@ -1,251 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file color4.inl - * @brief Inline implementation of aiColor4t<TReal> operators - */ -#pragma once -#ifndef AI_COLOR4D_INL_INC -#define AI_COLOR4D_INL_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -#include <assimp/color4.h> - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) { - r += o.r; - g += o.g; - b += o.b; - a += o.a; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) { - r -= o.r; - g -= o.g; - b -= o.b; - a -= o.a; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) { - r *= f; - g *= f; - b *= f; - a *= f; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) { - r /= f; - g /= f; - b /= f; - a /= f; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal aiColor4t<TReal>::operator[](unsigned int i) const { - switch ( i ) { - case 0: - return r; - case 1: - return g; - case 2: - return b; - case 3: - return a; - default: - break; - } - return r; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal& aiColor4t<TReal>::operator[](unsigned int i) { - switch ( i ) { - case 0: - return r; - case 1: - return g; - case 2: - return b; - case 3: - return a; - default: - break; - } - return r; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const { - return r == other.r && g == other.g && b == other.b && a == other.a; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const { - return r != other.r || g != other.g || b != other.b || a != other.a; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const { - return r < other.r || ( - r == other.r && ( - g < other.g || ( - g == other.g && ( - b < other.b || ( - b == other.b && ( - a < other.a - ) - ) - ) - ) - ) - ); -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { - return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { - return aiColor4t<TReal>( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { - return aiColor4t<TReal>( v1.r * v2.r, v1.g * v2.g, v1.b * v2.b, v1.a * v2.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { - return aiColor4t<TReal>( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) { - return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) { - return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) { - return v * (1/f); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) { - return aiColor4t<TReal>(f,f,f,f)/v; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) { - return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) { - return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) { - return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) { - return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a); -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiColor4t<TReal>::IsBlack() const { - // The alpha component doesn't care here. black is black. - static const TReal epsilon = 10e-3f; - return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon; -} - -#endif // __cplusplus -#endif // AI_VECTOR3D_INL_INC diff --git a/thirdparty/assimp/include/assimp/config.h b/thirdparty/assimp/include/assimp/config.h deleted file mode 100644 index 48d61941ad..0000000000 --- a/thirdparty/assimp/include/assimp/config.h +++ /dev/null @@ -1,1018 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2018, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file config.h - * @brief Defines constants for configurable properties for the library - * - * Typically these properties are set via - * #Assimp::Importer::SetPropertyFloat, - * #Assimp::Importer::SetPropertyInteger or - * #Assimp::Importer::SetPropertyString, - * depending on the data type of a property. All properties have a - * default value. See the doc for the mentioned methods for more details. - * - * <br><br> - * The corresponding functions for use with the plain-c API are: - * #aiSetImportPropertyInteger, - * #aiSetImportPropertyFloat, - * #aiSetImportPropertyString - */ -#pragma once -#ifndef AI_CONFIG_H_INC -#define AI_CONFIG_H_INC - - -// ########################################################################### -// LIBRARY SETTINGS -// General, global settings -// ########################################################################### - -// --------------------------------------------------------------------------- -/** @brief Enables time measurements. - * - * If enabled, measures the time needed for each part of the loading - * process (i.e. IO time, importing, postprocessing, ..) and dumps - * these timings to the DefaultLogger. See the @link perf Performance - * Page@endlink for more information on this topic. - * - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_GLOB_MEASURE_TIME \ - "GLOB_MEASURE_TIME" - - -// --------------------------------------------------------------------------- -/** @brief Global setting to disable generation of skeleton dummy meshes - * - * Skeleton dummy meshes are generated as a visualization aid in cases which - * the input data contains no geometry, but only animation data. - * Property data type: bool. Default value: false - */ -// --------------------------------------------------------------------------- -#define AI_CONFIG_IMPORT_NO_SKELETON_MESHES \ - "IMPORT_NO_SKELETON_MESHES" - - - -# if 0 // not implemented yet -// --------------------------------------------------------------------------- -/** @brief Set Assimp's multithreading policy. - * - * This setting is ignored if Assimp was built without boost.thread - * support (ASSIMP_BUILD_NO_THREADING, which is implied by ASSIMP_BUILD_BOOST_WORKAROUND). - * Possible values are: -1 to let Assimp decide what to do, 0 to disable - * multithreading entirely and any number larger than 0 to force a specific - * number of threads. Assimp is always free to ignore this settings, which is - * merely a hint. Usually, the default value (-1) will be fine. However, if - * Assimp is used concurrently from multiple user threads, it might be useful - * to limit each Importer instance to a specific number of cores. - * - * For more information, see the @link threading Threading page@endlink. - * Property type: int, default value: -1. - */ -#define AI_CONFIG_GLOB_MULTITHREADING \ - "GLOB_MULTITHREADING" -#endif - -// ########################################################################### -// POST PROCESSING SETTINGS -// Various stuff to fine-tune the behavior of a specific post processing step. -// ########################################################################### - - -// --------------------------------------------------------------------------- -/** @brief Maximum bone count per mesh for the SplitbyBoneCount step. - * - * Meshes are split until the maximum number of bones is reached. The default - * value is AI_SBBC_DEFAULT_MAX_BONES, which may be altered at - * compile-time. - * Property data type: integer. - */ -// --------------------------------------------------------------------------- -#define AI_CONFIG_PP_SBBC_MAX_BONES \ - "PP_SBBC_MAX_BONES" - - -// default limit for bone count -#if (!defined AI_SBBC_DEFAULT_MAX_BONES) -# define AI_SBBC_DEFAULT_MAX_BONES 60 -#endif - - -// --------------------------------------------------------------------------- -/** @brief Specifies the maximum angle that may be between two vertex tangents - * that their tangents and bi-tangents are smoothed. - * - * This applies to the CalcTangentSpace-Step. The angle is specified - * in degrees. The maximum value is 175. - * Property type: float. Default value: 45 degrees - */ -#define AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE \ - "PP_CT_MAX_SMOOTHING_ANGLE" - -// --------------------------------------------------------------------------- -/** @brief Source UV channel for tangent space computation. - * - * The specified channel must exist or an error will be raised. - * Property type: integer. Default value: 0 - */ -// --------------------------------------------------------------------------- -#define AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX \ - "PP_CT_TEXTURE_CHANNEL_INDEX" - -// --------------------------------------------------------------------------- -/** @brief Specifies the maximum angle that may be between two face normals - * at the same vertex position that their are smoothed together. - * - * Sometimes referred to as 'crease angle'. - * This applies to the GenSmoothNormals-Step. The angle is specified - * in degrees, so 180 is PI. The default value is 175 degrees (all vertex - * normals are smoothed). The maximum value is 175, too. Property type: float. - * Warning: setting this option may cause a severe loss of performance. The - * performance is unaffected if the #AI_CONFIG_FAVOUR_SPEED flag is set but - * the output quality may be reduced. - */ -#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE \ - "PP_GSN_MAX_SMOOTHING_ANGLE" - - -// --------------------------------------------------------------------------- -/** @brief Sets the colormap (= palette) to be used to decode embedded - * textures in MDL (Quake or 3DGS) files. - * - * This must be a valid path to a file. The file is 768 (256*3) bytes - * large and contains RGB triplets for each of the 256 palette entries. - * The default value is colormap.lmp. If the file is not found, - * a default palette (from Quake 1) is used. - * Property type: string. - */ -#define AI_CONFIG_IMPORT_MDL_COLORMAP \ - "IMPORT_MDL_COLORMAP" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_RemoveRedundantMaterials step to - * keep materials matching a name in a given list. - * - * This is a list of 1 to n strings, ' ' serves as delimiter character. - * Identifiers containing whitespaces must be enclosed in *single* - * quotation marks. For example:<tt> - * "keep-me and_me_to anotherMaterialToBeKept \'name with whitespace\'"</tt>. - * If a material matches on of these names, it will not be modified or - * removed by the postprocessing step nor will other materials be replaced - * by a reference to it. <br> - * This option might be useful if you are using some magic material names - * to pass additional semantics through the content pipeline. This ensures - * they won't be optimized away, but a general optimization is still - * performed for materials not contained in the list. - * Property type: String. Default value: n/a - * @note Linefeeds, tabs or carriage returns are treated as whitespace. - * Material names are case sensitive. - */ -#define AI_CONFIG_PP_RRM_EXCLUDE_LIST \ - "PP_RRM_EXCLUDE_LIST" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to - * keep the scene hierarchy. Meshes are moved to worldspace, but - * no optimization is performed (read: meshes with equal materials are not - * joined. The total number of meshes won't change). - * - * This option could be of use for you if the scene hierarchy contains - * important additional information which you intend to parse. - * For rendering, you can still render all meshes in the scene without - * any transformations. - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_PP_PTV_KEEP_HIERARCHY \ - "PP_PTV_KEEP_HIERARCHY" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to normalize - * all vertex components into the [-1,1] range. That is, a bounding box - * for the whole scene is computed, the maximum component is taken and all - * meshes are scaled appropriately (uniformly of course!). - * This might be useful if you don't know the spatial dimension of the input - * data*/ -#define AI_CONFIG_PP_PTV_NORMALIZE \ - "PP_PTV_NORMALIZE" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to use - * a users defined matrix as the scene root node transformation before - * transforming vertices. - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION \ - "PP_PTV_ADD_ROOT_TRANSFORMATION" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to use - * a users defined matrix as the scene root node transformation before - * transforming vertices. This property correspond to the 'a1' component - * of the transformation matrix. - * Property type: aiMatrix4x4. - */ -#define AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION \ - "PP_PTV_ROOT_TRANSFORMATION" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_FindDegenerates step to - * remove degenerated primitives from the import - immediately. - * - * The default behaviour converts degenerated triangles to lines and - * degenerated lines to points. See the documentation to the - * #aiProcess_FindDegenerates step for a detailed example of the various ways - * to get rid of these lines and points if you don't want them. - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_PP_FD_REMOVE \ - "PP_FD_REMOVE" - -// --------------------------------------------------------------------------- -/** - * @brief Configures the #aiProcess_FindDegenerates to check the area of a - * trinagle to be greates than e-6. If this is not the case the triangle will - * be removed if #AI_CONFIG_PP_FD_REMOVE is set to true. - */ -#define AI_CONFIG_PP_FD_CHECKAREA \ - "PP_FD_CHECKAREA" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes - * matching a name in a given list. - * - * This is a list of 1 to n strings, ' ' serves as delimiter character. - * Identifiers containing whitespaces must be enclosed in *single* - * quotation marks. For example:<tt> - * "keep-me and_me_to anotherNodeToBeKept \'name with whitespace\'"</tt>. - * If a node matches on of these names, it will not be modified or - * removed by the postprocessing step.<br> - * This option might be useful if you are using some magic node names - * to pass additional semantics through the content pipeline. This ensures - * they won't be optimized away, but a general optimization is still - * performed for nodes not contained in the list. - * Property type: String. Default value: n/a - * @note Linefeeds, tabs or carriage returns are treated as whitespace. - * Node names are case sensitive. - */ -#define AI_CONFIG_PP_OG_EXCLUDE_LIST \ - "PP_OG_EXCLUDE_LIST" - -// --------------------------------------------------------------------------- -/** @brief Set the maximum number of triangles in a mesh. - * - * This is used by the "SplitLargeMeshes" PostProcess-Step to determine - * whether a mesh must be split or not. - * @note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES - * Property type: integer. - */ -#define AI_CONFIG_PP_SLM_TRIANGLE_LIMIT \ - "PP_SLM_TRIANGLE_LIMIT" - -// default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT -#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES) -# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000 -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the maximum number of vertices in a mesh. - * - * This is used by the "SplitLargeMeshes" PostProcess-Step to determine - * whether a mesh must be split or not. - * @note The default value is AI_SLM_DEFAULT_MAX_VERTICES - * Property type: integer. - */ -#define AI_CONFIG_PP_SLM_VERTEX_LIMIT \ - "PP_SLM_VERTEX_LIMIT" - -// default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT -#if (!defined AI_SLM_DEFAULT_MAX_VERTICES) -# define AI_SLM_DEFAULT_MAX_VERTICES 1000000 -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the maximum number of bones affecting a single vertex - * - * This is used by the #aiProcess_LimitBoneWeights PostProcess-Step. - * @note The default value is AI_LMW_MAX_WEIGHTS - * Property type: integer.*/ -#define AI_CONFIG_PP_LBW_MAX_WEIGHTS \ - "PP_LBW_MAX_WEIGHTS" - -// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS -#if (!defined AI_LMW_MAX_WEIGHTS) -# define AI_LMW_MAX_WEIGHTS 0x4 -#endif // !! AI_LMW_MAX_WEIGHTS - -// --------------------------------------------------------------------------- -/** @brief Lower the deboning threshold in order to remove more bones. - * - * This is used by the #aiProcess_Debone PostProcess-Step. - * @note The default value is AI_DEBONE_THRESHOLD - * Property type: float.*/ -#define AI_CONFIG_PP_DB_THRESHOLD \ - "PP_DB_THRESHOLD" - -// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS -#if (!defined AI_DEBONE_THRESHOLD) -# define AI_DEBONE_THRESHOLD 1.0f -#endif // !! AI_DEBONE_THRESHOLD - -// --------------------------------------------------------------------------- -/** @brief Require all bones qualify for deboning before removing any - * - * This is used by the #aiProcess_Debone PostProcess-Step. - * @note The default value is 0 - * Property type: bool.*/ -#define AI_CONFIG_PP_DB_ALL_OR_NONE \ - "PP_DB_ALL_OR_NONE" - -/** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property - */ -#ifndef PP_ICL_PTCACHE_SIZE -# define PP_ICL_PTCACHE_SIZE 12 -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the size of the post-transform vertex cache to optimize the - * vertices for. This configures the #aiProcess_ImproveCacheLocality step. - * - * The size is given in vertices. Of course you can't know how the vertex - * format will exactly look like after the import returns, but you can still - * guess what your meshes will probably have. - * @note The default value is #PP_ICL_PTCACHE_SIZE. That results in slight - * performance improvements for most nVidia/AMD cards since 2002. - * Property type: integer. - */ -#define AI_CONFIG_PP_ICL_PTCACHE_SIZE "PP_ICL_PTCACHE_SIZE" - -// --------------------------------------------------------------------------- -/** @brief Enumerates components of the aiScene and aiMesh data structures - * that can be excluded from the import using the #aiProcess_RemoveComponent step. - * - * See the documentation to #aiProcess_RemoveComponent for more details. - */ -enum aiComponent -{ - /** Normal vectors */ -#ifdef SWIG - aiComponent_NORMALS = 0x2, -#else - aiComponent_NORMALS = 0x2u, -#endif - - /** Tangents and bitangents go always together ... */ -#ifdef SWIG - aiComponent_TANGENTS_AND_BITANGENTS = 0x4, -#else - aiComponent_TANGENTS_AND_BITANGENTS = 0x4u, -#endif - - /** ALL color sets - * Use aiComponent_COLORn(N) to specify the N'th set */ - aiComponent_COLORS = 0x8, - - /** ALL texture UV sets - * aiComponent_TEXCOORDn(N) to specify the N'th set */ - aiComponent_TEXCOORDS = 0x10, - - /** Removes all bone weights from all meshes. - * The scenegraph nodes corresponding to the bones are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_BONEWEIGHTS = 0x20, - - /** Removes all node animations (aiScene::mAnimations). - * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_ANIMATIONS = 0x40, - - /** Removes all embedded textures (aiScene::mTextures) */ - aiComponent_TEXTURES = 0x80, - - /** Removes all light sources (aiScene::mLights). - * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_LIGHTS = 0x100, - - /** Removes all cameras (aiScene::mCameras). - * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_CAMERAS = 0x200, - - /** Removes all meshes (aiScene::mMeshes). */ - aiComponent_MESHES = 0x400, - - /** Removes all materials. One default material will - * be generated, so aiScene::mNumMaterials will be 1. */ - aiComponent_MATERIALS = 0x800, - - - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. */ -#ifndef SWIG - _aiComponent_Force32Bit = 0x9fffffff -#endif -}; - -// Remove a specific color channel 'n' -#define aiComponent_COLORSn(n) (1u << (n+20u)) - -// Remove a specific UV channel 'n' -#define aiComponent_TEXCOORDSn(n) (1u << (n+25u)) - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_RemoveComponent step: - * Specifies the parts of the data structure to be removed. - * - * See the documentation to this step for further details. The property - * is expected to be an integer, a bitwise combination of the - * #aiComponent flags defined above in this header. The default - * value is 0. Important: if no valid mesh is remaining after the - * step has been executed (e.g you thought it was funny to specify ALL - * of the flags defined above) the import FAILS. Mainly because there is - * no data to work on anymore ... - */ -#define AI_CONFIG_PP_RVC_FLAGS \ - "PP_RVC_FLAGS" - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_SortByPType step: - * Specifies which primitive types are removed by the step. - * - * This is a bitwise combination of the aiPrimitiveType flags. - * Specifying all of them is illegal, of course. A typical use would - * be to exclude all line and point meshes from the import. This - * is an integer property, its default value is 0. - */ -#define AI_CONFIG_PP_SBP_REMOVE \ - "PP_SBP_REMOVE" - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_FindInvalidData step: - * Specifies the floating-point accuracy for animation values. The step - * checks for animation tracks where all frame values are absolutely equal - * and removes them. This tweakable controls the epsilon for floating-point - * comparisons - two keys are considered equal if the invariant - * abs(n0-n1)>epsilon holds true for all vector respectively quaternion - * components. The default value is 0.f - comparisons are exact then. - */ -#define AI_CONFIG_PP_FID_ANIM_ACCURACY \ - "PP_FID_ANIM_ACCURACY" - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_FindInvalidData step: - * Set to true to ignore texture coordinates. This may be useful if you have - * to assign different kind of textures like one for the summer or one for the winter. - */ -#define AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS \ - "PP_FID_IGNORE_TEXTURECOORDS" - -// TransformUVCoords evaluates UV scalings -#define AI_UVTRAFO_SCALING 0x1 - -// TransformUVCoords evaluates UV rotations -#define AI_UVTRAFO_ROTATION 0x2 - -// TransformUVCoords evaluates UV translation -#define AI_UVTRAFO_TRANSLATION 0x4 - -// Everything baked together -> default value -#define AI_UVTRAFO_ALL (AI_UVTRAFO_SCALING | AI_UVTRAFO_ROTATION | AI_UVTRAFO_TRANSLATION) - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_TransformUVCoords step: - * Specifies which UV transformations are evaluated. - * - * This is a bitwise combination of the AI_UVTRAFO_XXX flags (integer - * property, of course). By default all transformations are enabled - * (AI_UVTRAFO_ALL). - */ -#define AI_CONFIG_PP_TUV_EVALUATE \ - "PP_TUV_EVALUATE" - -// --------------------------------------------------------------------------- -/** @brief A hint to assimp to favour speed against import quality. - * - * Enabling this option may result in faster loading, but it needn't. - * It represents just a hint to loaders and post-processing steps to use - * faster code paths, if possible. - * This property is expected to be an integer, != 0 stands for true. - * The default value is 0. - */ -#define AI_CONFIG_FAVOUR_SPEED \ - "FAVOUR_SPEED" - - -// ########################################################################### -// IMPORTER SETTINGS -// Various stuff to fine-tune the behaviour of specific importer plugins. -// ########################################################################### - - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will merge all geometry layers present - * in the source file or take only the first. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS \ - "IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read all materials present in the - * source file or take only the referenced materials. - * - * This is void unless IMPORT_FBX_READ_MATERIALS=1. - * - * The default value is false (0) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS \ - "IMPORT_FBX_READ_ALL_MATERIALS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read materials. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_MATERIALS \ - "IMPORT_FBX_READ_MATERIALS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read embedded textures. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_TEXTURES \ - "IMPORT_FBX_READ_TEXTURES" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read cameras. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_CAMERAS \ - "IMPORT_FBX_READ_CAMERAS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read light sources. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_LIGHTS \ - "IMPORT_FBX_READ_LIGHTS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read animations. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS \ - "IMPORT_FBX_READ_ANIMATIONS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will act in strict mode in which only - * FBX 2013 is supported and any other sub formats are rejected. FBX 2013 - * is the primary target for the importer, so this format is best - * supported and well-tested. - * - * The default value is false (0) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_STRICT_MODE \ - "IMPORT_FBX_STRICT_MODE" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will preserve pivot points for - * transformations (as extra nodes). If set to false, pivots and offsets - * will be evaluated whenever possible. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS \ - "IMPORT_FBX_PRESERVE_PIVOTS" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the importer will drop empty animation curves or - * animation curves which match the bind pose transformation over their - * entire defined range. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \ - "IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will use the legacy embedded texture naming. - * - * The default value is false (0) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \ - "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" - -// --------------------------------------------------------------------------- -/** @brief Set wether the importer shall not remove empty bones. - * - * Empty bone are often used to define connections for other models. - */ -#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \ - "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES" - - -// --------------------------------------------------------------------------- -/** @brief Set wether the FBX importer shall convert the unit from cm to m. - */ -#define AI_CONFIG_FBX_CONVERT_TO_M \ - "AI_CONFIG_FBX_CONVERT_TO_M" - -// --------------------------------------------------------------------------- -/** @brief Set the vertex animation keyframe to be imported - * - * ASSIMP does not support vertex keyframes (only bone animation is supported). - * The library reads only one frame of models with vertex animations. - * By default this is the first frame. - * \note The default value is 0. This option applies to all importers. - * However, it is also possible to override the global setting - * for a specific loader. You can use the AI_CONFIG_IMPORT_XXX_KEYFRAME - * options (where XXX is a placeholder for the file format for which you - * want to override the global setting). - * Property type: integer. - */ -#define AI_CONFIG_IMPORT_GLOBAL_KEYFRAME "IMPORT_GLOBAL_KEYFRAME" - -#define AI_CONFIG_IMPORT_MD3_KEYFRAME "IMPORT_MD3_KEYFRAME" -#define AI_CONFIG_IMPORT_MD2_KEYFRAME "IMPORT_MD2_KEYFRAME" -#define AI_CONFIG_IMPORT_MDL_KEYFRAME "IMPORT_MDL_KEYFRAME" -#define AI_CONFIG_IMPORT_MDC_KEYFRAME "IMPORT_MDC_KEYFRAME" -#define AI_CONFIG_IMPORT_SMD_KEYFRAME "IMPORT_SMD_KEYFRAME" -#define AI_CONFIG_IMPORT_UNREAL_KEYFRAME "IMPORT_UNREAL_KEYFRAME" - -// --------------------------------------------------------------------------- -/** Smd load multiple animations - * - * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_SMD_LOAD_ANIMATION_LIST "IMPORT_SMD_LOAD_ANIMATION_LIST" - -// --------------------------------------------------------------------------- -/** @brief Configures the AC loader to collect all surfaces which have the - * "Backface cull" flag set in separate meshes. - * - * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL \ - "IMPORT_AC_SEPARATE_BFCULL" - -// --------------------------------------------------------------------------- -/** @brief Configures whether the AC loader evaluates subdivision surfaces ( - * indicated by the presence of the 'subdiv' attribute in the file). By - * default, Assimp performs the subdivision using the standard - * Catmull-Clark algorithm - * - * * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION \ - "IMPORT_AC_EVAL_SUBDIVISION" - -// --------------------------------------------------------------------------- -/** @brief Configures the UNREAL 3D loader to separate faces with different - * surface flags (e.g. two-sided vs. single-sided). - * - * * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \ - "UNREAL_HANDLE_FLAGS" - -// --------------------------------------------------------------------------- -/** @brief Configures the terragen import plugin to compute uv's for - * terrains, if not given. Furthermore a default texture is assigned. - * - * UV coordinates for terrains are so simple to compute that you'll usually - * want to compute them on your own, if you need them. This option is intended - * for model viewers which want to offer an easy way to apply textures to - * terrains. - * * Property type: bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_TER_MAKE_UVS \ - "IMPORT_TER_MAKE_UVS" - -// --------------------------------------------------------------------------- -/** @brief Configures the ASE loader to always reconstruct normal vectors - * basing on the smoothing groups loaded from the file. - * - * Some ASE files have carry invalid normals, other don't. - * * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS \ - "IMPORT_ASE_RECONSTRUCT_NORMALS" - -// --------------------------------------------------------------------------- -/** @brief Configures the M3D loader to detect and process multi-part - * Quake player models. - * - * These models usually consist of 3 files, lower.md3, upper.md3 and - * head.md3. If this property is set to true, Assimp will try to load and - * combine all three files if one of them is loaded. - * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \ - "IMPORT_MD3_HANDLE_MULTIPART" - -// --------------------------------------------------------------------------- -/** @brief Tells the MD3 loader which skin files to load. - * - * When loading MD3 files, Assimp checks whether a file - * [md3_file_name]_[skin_name].skin is existing. These files are used by - * Quake III to be able to assign different skins (e.g. red and blue team) - * to models. 'default', 'red', 'blue' are typical skin names. - * Property type: String. Default value: "default". - */ -#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ - "IMPORT_MD3_SKIN_NAME" - -// --------------------------------------------------------------------------- -/** @brief Specify the Quake 3 shader file to be used for a particular - * MD3 file. This can also be a search path. - * - * By default Assimp's behaviour is as follows: If a MD3 file - * <tt>any_path/models/any_q3_subdir/model_name/file_name.md3</tt> is - * loaded, the library tries to locate the corresponding shader file in - * <tt>any_path/scripts/model_name.shader</tt>. This property overrides this - * behaviour. It can either specify a full path to the shader to be loaded - * or alternatively the path (relative or absolute) to the directory where - * the shaders for all MD3s to be loaded reside. Assimp attempts to open - * <tt>IMPORT_MD3_SHADER_SRC/model_name.shader</tt> first, <tt>IMPORT_MD3_SHADER_SRC/file_name.shader</tt> - * is the fallback file. Note that IMPORT_MD3_SHADER_SRC should have a terminal (back)slash. - * Property type: String. Default value: n/a. - */ -#define AI_CONFIG_IMPORT_MD3_SHADER_SRC \ - "IMPORT_MD3_SHADER_SRC" - -// --------------------------------------------------------------------------- -/** @brief Configures the LWO loader to load just one layer from the model. - * - * LWO files consist of layers and in some cases it could be useful to load - * only one of them. This property can be either a string - which specifies - * the name of the layer - or an integer - the index of the layer. If the - * property is not set the whole LWO model is loaded. Loading fails if the - * requested layer is not available. The layer index is zero-based and the - * layer name may not be empty.<br> - * Property type: Integer. Default value: all layers are loaded. - */ -#define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY \ - "IMPORT_LWO_ONE_LAYER_ONLY" - -// --------------------------------------------------------------------------- -/** @brief Configures the MD5 loader to not load the MD5ANIM file for - * a MD5MESH file automatically. - * - * The default strategy is to look for a file with the same name but the - * MD5ANIM extension in the same directory. If it is found, it is loaded - * and combined with the MD5MESH file. This configuration option can be - * used to disable this behaviour. - * - * * Property type: bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD \ - "IMPORT_MD5_NO_ANIM_AUTOLOAD" - -// --------------------------------------------------------------------------- -/** @brief Defines the begin of the time range for which the LWS loader - * evaluates animations and computes aiNodeAnim's. - * - * Assimp provides full conversion of LightWave's envelope system, including - * pre and post conditions. The loader computes linearly subsampled animation - * chanels with the frame rate given in the LWS file. This property defines - * the start time. Note: animation channels are only generated if a node - * has at least one envelope with more tan one key assigned. This property. - * is given in frames, '0' is the first frame. By default, if this property - * is not set, the importer takes the animation start from the input LWS - * file ('FirstFrame' line)<br> - * Property type: Integer. Default value: taken from file. - * - * @see AI_CONFIG_IMPORT_LWS_ANIM_END - end of the imported time range - */ -#define AI_CONFIG_IMPORT_LWS_ANIM_START \ - "IMPORT_LWS_ANIM_START" -#define AI_CONFIG_IMPORT_LWS_ANIM_END \ - "IMPORT_LWS_ANIM_END" - -// --------------------------------------------------------------------------- -/** @brief Defines the output frame rate of the IRR loader. - * - * IRR animations are difficult to convert for Assimp and there will - * always be a loss of quality. This setting defines how many keys per second - * are returned by the converter.<br> - * Property type: integer. Default value: 100 - */ -#define AI_CONFIG_IMPORT_IRR_ANIM_FPS \ - "IMPORT_IRR_ANIM_FPS" - -// --------------------------------------------------------------------------- -/** @brief Ogre Importer will try to find referenced materials from this file. - * - * Ogre meshes reference with material names, this does not tell Assimp the file - * where it is located in. Assimp will try to find the source file in the following - * order: <material-name>.material, <mesh-filename-base>.material and - * lastly the material name defined by this config property. - * <br> - * Property type: String. Default value: Scene.material. - */ -#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE \ - "IMPORT_OGRE_MATERIAL_FILE" - -// --------------------------------------------------------------------------- -/** @brief Ogre Importer detect the texture usage from its filename. - * - * Ogre material texture units do not define texture type, the textures usage - * depends on the used shader or Ogre's fixed pipeline. If this config property - * is true Assimp will try to detect the type from the textures filename postfix: - * _n, _nrm, _nrml, _normal, _normals and _normalmap for normal map, _s, _spec, - * _specular and _specularmap for specular map, _l, _light, _lightmap, _occ - * and _occlusion for light map, _disp and _displacement for displacement map. - * The matching is case insensitive. Post fix is taken between the last - * underscore and the last period. - * Default behavior is to detect type from lower cased texture unit name by - * matching against: normalmap, specularmap, lightmap and displacementmap. - * For both cases if no match is found aiTextureType_DIFFUSE is used. - * <br> - * Property type: Bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME \ - "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME" - - /** @brief Specifies whether the Android JNI asset extraction is supported. - * - * Turn on this option if you want to manage assets in native - * Android application without having to keep the internal directory and asset - * manager pointer. - */ - #define AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT "AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the IFC loader skips over IfcSpace elements. - * - * IfcSpace elements (and their geometric representations) are used to - * represent, well, free space in a building storey.<br> - * Property type: Bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the IFC loader will use its own, custom triangulation - * algorithm to triangulate wall and floor meshes. - * - * If this property is set to false, walls will be either triangulated by - * #aiProcess_Triangulate or will be passed through as huge polygons with - * faked holes (i.e. holes that are connected with the outer boundary using - * a dummy edge). It is highly recommended to set this property to true - * if you want triangulated data because #aiProcess_Triangulate is known to - * have problems with the kind of polygons that the IFC loader spits out for - * complicated meshes. - * Property type: Bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION" - -// --------------------------------------------------------------------------- -/** @brief Set the tessellation conic angle for IFC smoothing curves. - * - * This is used by the IFC importer to determine the tessellation parameter - * for smoothing curves. - * @note The default value is AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE and the - * accepted values are in range [5.0, 120.0]. - * Property type: Float. - */ -#define AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE "IMPORT_IFC_SMOOTHING_ANGLE" - -// default value for AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE -#if (!defined AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE) -# define AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE 10.0f -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the tessellation for IFC cylindrical shapes. - * - * This is used by the IFC importer to determine the tessellation parameter - * for cylindrical shapes, i.e. the number of segments used to approximate a circle. - * @note The default value is AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION and the - * accepted values are in range [3, 180]. - * Property type: Integer. - */ -#define AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION "IMPORT_IFC_CYLINDRICAL_TESSELLATION" - -// default value for AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION -#if (!defined AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION) -# define AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION 32 -#endif - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the Collada loader will ignore the provided up direction. - * - * If this property is set to true, the up direction provided in the file header will - * be ignored and the file will be loaded as is. - * Property type: Bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the Collada loader should use Collada names as node names. - * - * If this property is set to true, the Collada names will be used as the - * node name. The default is to use the id tag (resp. sid tag, if no id tag is present) - * instead. - * Property type: Bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES "IMPORT_COLLADA_USE_COLLADA_NAMES" - -// ---------- All the Export defines ------------ - -/** @brief Specifies the xfile use double for real values of float - * - * Property type: Bool. Default value: false. - */ - -#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT" - -/** @brief Specifies whether the assimp export shall be able to export point clouds - * - * When this flag is not defined the render data has to contain valid faces. - * Point clouds are only a collection of vertices which have nor spatial organization - * by a face and the validation process will remove them. Enabling this feature will - * switch off the flag and enable the functionality to export pure point clouds. - */ -#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS" - -/** - * @brief Specifies a gobal key factor for scale, float value - */ -#define AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY "GLOBAL_SCALE_FACTOR" - -#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT) -# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f -#endif // !! AI_DEBONE_THRESHOLD - -#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR" - -#if (!defined AI_CONFIG_APP_SCALE_KEY) -# define AI_CONFIG_APP_SCALE_KEY 1.0 -#endif // AI_CONFIG_APP_SCALE_KEY - - -// ---------- All the Build/Compile-time defines ------------ - -/** @brief Specifies if double precision is supported inside assimp - * - * Property type: Bool. Default value: undefined. - */ - -/* #undef ASSIMP_DOUBLE_PRECISION */ - -#endif // !! AI_CONFIG_H_INC diff --git a/thirdparty/assimp/include/assimp/config.h.in b/thirdparty/assimp/include/assimp/config.h.in deleted file mode 100644 index 3a6379bf40..0000000000 --- a/thirdparty/assimp/include/assimp/config.h.in +++ /dev/null @@ -1,1018 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2018, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file config.h - * @brief Defines constants for configurable properties for the library - * - * Typically these properties are set via - * #Assimp::Importer::SetPropertyFloat, - * #Assimp::Importer::SetPropertyInteger or - * #Assimp::Importer::SetPropertyString, - * depending on the data type of a property. All properties have a - * default value. See the doc for the mentioned methods for more details. - * - * <br><br> - * The corresponding functions for use with the plain-c API are: - * #aiSetImportPropertyInteger, - * #aiSetImportPropertyFloat, - * #aiSetImportPropertyString - */ -#pragma once -#ifndef AI_CONFIG_H_INC -#define AI_CONFIG_H_INC - - -// ########################################################################### -// LIBRARY SETTINGS -// General, global settings -// ########################################################################### - -// --------------------------------------------------------------------------- -/** @brief Enables time measurements. - * - * If enabled, measures the time needed for each part of the loading - * process (i.e. IO time, importing, postprocessing, ..) and dumps - * these timings to the DefaultLogger. See the @link perf Performance - * Page@endlink for more information on this topic. - * - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_GLOB_MEASURE_TIME \ - "GLOB_MEASURE_TIME" - - -// --------------------------------------------------------------------------- -/** @brief Global setting to disable generation of skeleton dummy meshes - * - * Skeleton dummy meshes are generated as a visualization aid in cases which - * the input data contains no geometry, but only animation data. - * Property data type: bool. Default value: false - */ -// --------------------------------------------------------------------------- -#define AI_CONFIG_IMPORT_NO_SKELETON_MESHES \ - "IMPORT_NO_SKELETON_MESHES" - - - -# if 0 // not implemented yet -// --------------------------------------------------------------------------- -/** @brief Set Assimp's multithreading policy. - * - * This setting is ignored if Assimp was built without boost.thread - * support (ASSIMP_BUILD_NO_THREADING, which is implied by ASSIMP_BUILD_BOOST_WORKAROUND). - * Possible values are: -1 to let Assimp decide what to do, 0 to disable - * multithreading entirely and any number larger than 0 to force a specific - * number of threads. Assimp is always free to ignore this settings, which is - * merely a hint. Usually, the default value (-1) will be fine. However, if - * Assimp is used concurrently from multiple user threads, it might be useful - * to limit each Importer instance to a specific number of cores. - * - * For more information, see the @link threading Threading page@endlink. - * Property type: int, default value: -1. - */ -#define AI_CONFIG_GLOB_MULTITHREADING \ - "GLOB_MULTITHREADING" -#endif - -// ########################################################################### -// POST PROCESSING SETTINGS -// Various stuff to fine-tune the behavior of a specific post processing step. -// ########################################################################### - - -// --------------------------------------------------------------------------- -/** @brief Maximum bone count per mesh for the SplitbyBoneCount step. - * - * Meshes are split until the maximum number of bones is reached. The default - * value is AI_SBBC_DEFAULT_MAX_BONES, which may be altered at - * compile-time. - * Property data type: integer. - */ -// --------------------------------------------------------------------------- -#define AI_CONFIG_PP_SBBC_MAX_BONES \ - "PP_SBBC_MAX_BONES" - - -// default limit for bone count -#if (!defined AI_SBBC_DEFAULT_MAX_BONES) -# define AI_SBBC_DEFAULT_MAX_BONES 60 -#endif - - -// --------------------------------------------------------------------------- -/** @brief Specifies the maximum angle that may be between two vertex tangents - * that their tangents and bi-tangents are smoothed. - * - * This applies to the CalcTangentSpace-Step. The angle is specified - * in degrees. The maximum value is 175. - * Property type: float. Default value: 45 degrees - */ -#define AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE \ - "PP_CT_MAX_SMOOTHING_ANGLE" - -// --------------------------------------------------------------------------- -/** @brief Source UV channel for tangent space computation. - * - * The specified channel must exist or an error will be raised. - * Property type: integer. Default value: 0 - */ -// --------------------------------------------------------------------------- -#define AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX \ - "PP_CT_TEXTURE_CHANNEL_INDEX" - -// --------------------------------------------------------------------------- -/** @brief Specifies the maximum angle that may be between two face normals - * at the same vertex position that their are smoothed together. - * - * Sometimes referred to as 'crease angle'. - * This applies to the GenSmoothNormals-Step. The angle is specified - * in degrees, so 180 is PI. The default value is 175 degrees (all vertex - * normals are smoothed). The maximum value is 175, too. Property type: float. - * Warning: setting this option may cause a severe loss of performance. The - * performance is unaffected if the #AI_CONFIG_FAVOUR_SPEED flag is set but - * the output quality may be reduced. - */ -#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE \ - "PP_GSN_MAX_SMOOTHING_ANGLE" - - -// --------------------------------------------------------------------------- -/** @brief Sets the colormap (= palette) to be used to decode embedded - * textures in MDL (Quake or 3DGS) files. - * - * This must be a valid path to a file. The file is 768 (256*3) bytes - * large and contains RGB triplets for each of the 256 palette entries. - * The default value is colormap.lmp. If the file is not found, - * a default palette (from Quake 1) is used. - * Property type: string. - */ -#define AI_CONFIG_IMPORT_MDL_COLORMAP \ - "IMPORT_MDL_COLORMAP" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_RemoveRedundantMaterials step to - * keep materials matching a name in a given list. - * - * This is a list of 1 to n strings, ' ' serves as delimiter character. - * Identifiers containing whitespaces must be enclosed in *single* - * quotation marks. For example:<tt> - * "keep-me and_me_to anotherMaterialToBeKept \'name with whitespace\'"</tt>. - * If a material matches on of these names, it will not be modified or - * removed by the postprocessing step nor will other materials be replaced - * by a reference to it. <br> - * This option might be useful if you are using some magic material names - * to pass additional semantics through the content pipeline. This ensures - * they won't be optimized away, but a general optimization is still - * performed for materials not contained in the list. - * Property type: String. Default value: n/a - * @note Linefeeds, tabs or carriage returns are treated as whitespace. - * Material names are case sensitive. - */ -#define AI_CONFIG_PP_RRM_EXCLUDE_LIST \ - "PP_RRM_EXCLUDE_LIST" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to - * keep the scene hierarchy. Meshes are moved to worldspace, but - * no optimization is performed (read: meshes with equal materials are not - * joined. The total number of meshes won't change). - * - * This option could be of use for you if the scene hierarchy contains - * important additional information which you intend to parse. - * For rendering, you can still render all meshes in the scene without - * any transformations. - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_PP_PTV_KEEP_HIERARCHY \ - "PP_PTV_KEEP_HIERARCHY" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to normalize - * all vertex components into the [-1,1] range. That is, a bounding box - * for the whole scene is computed, the maximum component is taken and all - * meshes are scaled appropriately (uniformly of course!). - * This might be useful if you don't know the spatial dimension of the input - * data*/ -#define AI_CONFIG_PP_PTV_NORMALIZE \ - "PP_PTV_NORMALIZE" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to use - * a users defined matrix as the scene root node transformation before - * transforming vertices. - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION \ - "PP_PTV_ADD_ROOT_TRANSFORMATION" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_PreTransformVertices step to use - * a users defined matrix as the scene root node transformation before - * transforming vertices. This property correspond to the 'a1' component - * of the transformation matrix. - * Property type: aiMatrix4x4. - */ -#define AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION \ - "PP_PTV_ROOT_TRANSFORMATION" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_FindDegenerates step to - * remove degenerated primitives from the import - immediately. - * - * The default behaviour converts degenerated triangles to lines and - * degenerated lines to points. See the documentation to the - * #aiProcess_FindDegenerates step for a detailed example of the various ways - * to get rid of these lines and points if you don't want them. - * Property type: bool. Default value: false. - */ -#define AI_CONFIG_PP_FD_REMOVE \ - "PP_FD_REMOVE" - -// --------------------------------------------------------------------------- -/** - * @brief Configures the #aiProcess_FindDegenerates to check the area of a - * trinagle to be greates than e-6. If this is not the case the triangle will - * be removed if #AI_CONFIG_PP_FD_REMOVE is set to true. - */ -#define AI_CONFIG_PP_FD_CHECKAREA \ - "PP_FD_CHECKAREA" - -// --------------------------------------------------------------------------- -/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes - * matching a name in a given list. - * - * This is a list of 1 to n strings, ' ' serves as delimiter character. - * Identifiers containing whitespaces must be enclosed in *single* - * quotation marks. For example:<tt> - * "keep-me and_me_to anotherNodeToBeKept \'name with whitespace\'"</tt>. - * If a node matches on of these names, it will not be modified or - * removed by the postprocessing step.<br> - * This option might be useful if you are using some magic node names - * to pass additional semantics through the content pipeline. This ensures - * they won't be optimized away, but a general optimization is still - * performed for nodes not contained in the list. - * Property type: String. Default value: n/a - * @note Linefeeds, tabs or carriage returns are treated as whitespace. - * Node names are case sensitive. - */ -#define AI_CONFIG_PP_OG_EXCLUDE_LIST \ - "PP_OG_EXCLUDE_LIST" - -// --------------------------------------------------------------------------- -/** @brief Set the maximum number of triangles in a mesh. - * - * This is used by the "SplitLargeMeshes" PostProcess-Step to determine - * whether a mesh must be split or not. - * @note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES - * Property type: integer. - */ -#define AI_CONFIG_PP_SLM_TRIANGLE_LIMIT \ - "PP_SLM_TRIANGLE_LIMIT" - -// default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT -#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES) -# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000 -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the maximum number of vertices in a mesh. - * - * This is used by the "SplitLargeMeshes" PostProcess-Step to determine - * whether a mesh must be split or not. - * @note The default value is AI_SLM_DEFAULT_MAX_VERTICES - * Property type: integer. - */ -#define AI_CONFIG_PP_SLM_VERTEX_LIMIT \ - "PP_SLM_VERTEX_LIMIT" - -// default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT -#if (!defined AI_SLM_DEFAULT_MAX_VERTICES) -# define AI_SLM_DEFAULT_MAX_VERTICES 1000000 -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the maximum number of bones affecting a single vertex - * - * This is used by the #aiProcess_LimitBoneWeights PostProcess-Step. - * @note The default value is AI_LMW_MAX_WEIGHTS - * Property type: integer.*/ -#define AI_CONFIG_PP_LBW_MAX_WEIGHTS \ - "PP_LBW_MAX_WEIGHTS" - -// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS -#if (!defined AI_LMW_MAX_WEIGHTS) -# define AI_LMW_MAX_WEIGHTS 0x4 -#endif // !! AI_LMW_MAX_WEIGHTS - -// --------------------------------------------------------------------------- -/** @brief Lower the deboning threshold in order to remove more bones. - * - * This is used by the #aiProcess_Debone PostProcess-Step. - * @note The default value is AI_DEBONE_THRESHOLD - * Property type: float.*/ -#define AI_CONFIG_PP_DB_THRESHOLD \ - "PP_DB_THRESHOLD" - -// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS -#if (!defined AI_DEBONE_THRESHOLD) -# define AI_DEBONE_THRESHOLD 1.0f -#endif // !! AI_DEBONE_THRESHOLD - -// --------------------------------------------------------------------------- -/** @brief Require all bones qualify for deboning before removing any - * - * This is used by the #aiProcess_Debone PostProcess-Step. - * @note The default value is 0 - * Property type: bool.*/ -#define AI_CONFIG_PP_DB_ALL_OR_NONE \ - "PP_DB_ALL_OR_NONE" - -/** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property - */ -#ifndef PP_ICL_PTCACHE_SIZE -# define PP_ICL_PTCACHE_SIZE 12 -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the size of the post-transform vertex cache to optimize the - * vertices for. This configures the #aiProcess_ImproveCacheLocality step. - * - * The size is given in vertices. Of course you can't know how the vertex - * format will exactly look like after the import returns, but you can still - * guess what your meshes will probably have. - * @note The default value is #PP_ICL_PTCACHE_SIZE. That results in slight - * performance improvements for most nVidia/AMD cards since 2002. - * Property type: integer. - */ -#define AI_CONFIG_PP_ICL_PTCACHE_SIZE "PP_ICL_PTCACHE_SIZE" - -// --------------------------------------------------------------------------- -/** @brief Enumerates components of the aiScene and aiMesh data structures - * that can be excluded from the import using the #aiProcess_RemoveComponent step. - * - * See the documentation to #aiProcess_RemoveComponent for more details. - */ -enum aiComponent -{ - /** Normal vectors */ -#ifdef SWIG - aiComponent_NORMALS = 0x2, -#else - aiComponent_NORMALS = 0x2u, -#endif - - /** Tangents and bitangents go always together ... */ -#ifdef SWIG - aiComponent_TANGENTS_AND_BITANGENTS = 0x4, -#else - aiComponent_TANGENTS_AND_BITANGENTS = 0x4u, -#endif - - /** ALL color sets - * Use aiComponent_COLORn(N) to specify the N'th set */ - aiComponent_COLORS = 0x8, - - /** ALL texture UV sets - * aiComponent_TEXCOORDn(N) to specify the N'th set */ - aiComponent_TEXCOORDS = 0x10, - - /** Removes all bone weights from all meshes. - * The scenegraph nodes corresponding to the bones are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_BONEWEIGHTS = 0x20, - - /** Removes all node animations (aiScene::mAnimations). - * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_ANIMATIONS = 0x40, - - /** Removes all embedded textures (aiScene::mTextures) */ - aiComponent_TEXTURES = 0x80, - - /** Removes all light sources (aiScene::mLights). - * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_LIGHTS = 0x100, - - /** Removes all cameras (aiScene::mCameras). - * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this */ - aiComponent_CAMERAS = 0x200, - - /** Removes all meshes (aiScene::mMeshes). */ - aiComponent_MESHES = 0x400, - - /** Removes all materials. One default material will - * be generated, so aiScene::mNumMaterials will be 1. */ - aiComponent_MATERIALS = 0x800, - - - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. */ -#ifndef SWIG - _aiComponent_Force32Bit = 0x9fffffff -#endif -}; - -// Remove a specific color channel 'n' -#define aiComponent_COLORSn(n) (1u << (n+20u)) - -// Remove a specific UV channel 'n' -#define aiComponent_TEXCOORDSn(n) (1u << (n+25u)) - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_RemoveComponent step: - * Specifies the parts of the data structure to be removed. - * - * See the documentation to this step for further details. The property - * is expected to be an integer, a bitwise combination of the - * #aiComponent flags defined above in this header. The default - * value is 0. Important: if no valid mesh is remaining after the - * step has been executed (e.g you thought it was funny to specify ALL - * of the flags defined above) the import FAILS. Mainly because there is - * no data to work on anymore ... - */ -#define AI_CONFIG_PP_RVC_FLAGS \ - "PP_RVC_FLAGS" - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_SortByPType step: - * Specifies which primitive types are removed by the step. - * - * This is a bitwise combination of the aiPrimitiveType flags. - * Specifying all of them is illegal, of course. A typical use would - * be to exclude all line and point meshes from the import. This - * is an integer property, its default value is 0. - */ -#define AI_CONFIG_PP_SBP_REMOVE \ - "PP_SBP_REMOVE" - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_FindInvalidData step: - * Specifies the floating-point accuracy for animation values. The step - * checks for animation tracks where all frame values are absolutely equal - * and removes them. This tweakable controls the epsilon for floating-point - * comparisons - two keys are considered equal if the invariant - * abs(n0-n1)>epsilon holds true for all vector respectively quaternion - * components. The default value is 0.f - comparisons are exact then. - */ -#define AI_CONFIG_PP_FID_ANIM_ACCURACY \ - "PP_FID_ANIM_ACCURACY" - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_FindInvalidData step: - * Set to true to ignore texture coordinates. This may be useful if you have - * to assign different kind of textures like one for the summer or one for the winter. - */ -#define AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS \ - "PP_FID_IGNORE_TEXTURECOORDS" - -// TransformUVCoords evaluates UV scalings -#define AI_UVTRAFO_SCALING 0x1 - -// TransformUVCoords evaluates UV rotations -#define AI_UVTRAFO_ROTATION 0x2 - -// TransformUVCoords evaluates UV translation -#define AI_UVTRAFO_TRANSLATION 0x4 - -// Everything baked together -> default value -#define AI_UVTRAFO_ALL (AI_UVTRAFO_SCALING | AI_UVTRAFO_ROTATION | AI_UVTRAFO_TRANSLATION) - -// --------------------------------------------------------------------------- -/** @brief Input parameter to the #aiProcess_TransformUVCoords step: - * Specifies which UV transformations are evaluated. - * - * This is a bitwise combination of the AI_UVTRAFO_XXX flags (integer - * property, of course). By default all transformations are enabled - * (AI_UVTRAFO_ALL). - */ -#define AI_CONFIG_PP_TUV_EVALUATE \ - "PP_TUV_EVALUATE" - -// --------------------------------------------------------------------------- -/** @brief A hint to assimp to favour speed against import quality. - * - * Enabling this option may result in faster loading, but it needn't. - * It represents just a hint to loaders and post-processing steps to use - * faster code paths, if possible. - * This property is expected to be an integer, != 0 stands for true. - * The default value is 0. - */ -#define AI_CONFIG_FAVOUR_SPEED \ - "FAVOUR_SPEED" - - -// ########################################################################### -// IMPORTER SETTINGS -// Various stuff to fine-tune the behaviour of specific importer plugins. -// ########################################################################### - - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will merge all geometry layers present - * in the source file or take only the first. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS \ - "IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read all materials present in the - * source file or take only the referenced materials. - * - * This is void unless IMPORT_FBX_READ_MATERIALS=1. - * - * The default value is false (0) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS \ - "IMPORT_FBX_READ_ALL_MATERIALS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read materials. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_MATERIALS \ - "IMPORT_FBX_READ_MATERIALS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read embedded textures. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_TEXTURES \ - "IMPORT_FBX_READ_TEXTURES" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read cameras. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_CAMERAS \ - "IMPORT_FBX_READ_CAMERAS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read light sources. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_LIGHTS \ - "IMPORT_FBX_READ_LIGHTS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will read animations. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS \ - "IMPORT_FBX_READ_ANIMATIONS" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will act in strict mode in which only - * FBX 2013 is supported and any other sub formats are rejected. FBX 2013 - * is the primary target for the importer, so this format is best - * supported and well-tested. - * - * The default value is false (0) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_STRICT_MODE \ - "IMPORT_FBX_STRICT_MODE" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will preserve pivot points for - * transformations (as extra nodes). If set to false, pivots and offsets - * will be evaluated whenever possible. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS \ - "IMPORT_FBX_PRESERVE_PIVOTS" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the importer will drop empty animation curves or - * animation curves which match the bind pose transformation over their - * entire defined range. - * - * The default value is true (1) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \ - "IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES" - -// --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will use the legacy embedded texture naming. - * - * The default value is false (0) - * Property type: bool - */ -#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \ - "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" - -// --------------------------------------------------------------------------- -/** @brief Set wether the importer shall not remove empty bones. - * - * Empty bone are often used to define connections for other models. - */ -#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \ - "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES" - - -// --------------------------------------------------------------------------- -/** @brief Set wether the FBX importer shall convert the unit from cm to m. - */ -#define AI_CONFIG_FBX_CONVERT_TO_M \ - "AI_CONFIG_FBX_CONVERT_TO_M" - -// --------------------------------------------------------------------------- -/** @brief Set the vertex animation keyframe to be imported - * - * ASSIMP does not support vertex keyframes (only bone animation is supported). - * The library reads only one frame of models with vertex animations. - * By default this is the first frame. - * \note The default value is 0. This option applies to all importers. - * However, it is also possible to override the global setting - * for a specific loader. You can use the AI_CONFIG_IMPORT_XXX_KEYFRAME - * options (where XXX is a placeholder for the file format for which you - * want to override the global setting). - * Property type: integer. - */ -#define AI_CONFIG_IMPORT_GLOBAL_KEYFRAME "IMPORT_GLOBAL_KEYFRAME" - -#define AI_CONFIG_IMPORT_MD3_KEYFRAME "IMPORT_MD3_KEYFRAME" -#define AI_CONFIG_IMPORT_MD2_KEYFRAME "IMPORT_MD2_KEYFRAME" -#define AI_CONFIG_IMPORT_MDL_KEYFRAME "IMPORT_MDL_KEYFRAME" -#define AI_CONFIG_IMPORT_MDC_KEYFRAME "IMPORT_MDC_KEYFRAME" -#define AI_CONFIG_IMPORT_SMD_KEYFRAME "IMPORT_SMD_KEYFRAME" -#define AI_CONFIG_IMPORT_UNREAL_KEYFRAME "IMPORT_UNREAL_KEYFRAME" - -// --------------------------------------------------------------------------- -/** Smd load multiple animations - * - * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_SMD_LOAD_ANIMATION_LIST "IMPORT_SMD_LOAD_ANIMATION_LIST" - -// --------------------------------------------------------------------------- -/** @brief Configures the AC loader to collect all surfaces which have the - * "Backface cull" flag set in separate meshes. - * - * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL \ - "IMPORT_AC_SEPARATE_BFCULL" - -// --------------------------------------------------------------------------- -/** @brief Configures whether the AC loader evaluates subdivision surfaces ( - * indicated by the presence of the 'subdiv' attribute in the file). By - * default, Assimp performs the subdivision using the standard - * Catmull-Clark algorithm - * - * * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION \ - "IMPORT_AC_EVAL_SUBDIVISION" - -// --------------------------------------------------------------------------- -/** @brief Configures the UNREAL 3D loader to separate faces with different - * surface flags (e.g. two-sided vs. single-sided). - * - * * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \ - "UNREAL_HANDLE_FLAGS" - -// --------------------------------------------------------------------------- -/** @brief Configures the terragen import plugin to compute uv's for - * terrains, if not given. Furthermore a default texture is assigned. - * - * UV coordinates for terrains are so simple to compute that you'll usually - * want to compute them on your own, if you need them. This option is intended - * for model viewers which want to offer an easy way to apply textures to - * terrains. - * * Property type: bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_TER_MAKE_UVS \ - "IMPORT_TER_MAKE_UVS" - -// --------------------------------------------------------------------------- -/** @brief Configures the ASE loader to always reconstruct normal vectors - * basing on the smoothing groups loaded from the file. - * - * Some ASE files have carry invalid normals, other don't. - * * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS \ - "IMPORT_ASE_RECONSTRUCT_NORMALS" - -// --------------------------------------------------------------------------- -/** @brief Configures the M3D loader to detect and process multi-part - * Quake player models. - * - * These models usually consist of 3 files, lower.md3, upper.md3 and - * head.md3. If this property is set to true, Assimp will try to load and - * combine all three files if one of them is loaded. - * Property type: bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \ - "IMPORT_MD3_HANDLE_MULTIPART" - -// --------------------------------------------------------------------------- -/** @brief Tells the MD3 loader which skin files to load. - * - * When loading MD3 files, Assimp checks whether a file - * [md3_file_name]_[skin_name].skin is existing. These files are used by - * Quake III to be able to assign different skins (e.g. red and blue team) - * to models. 'default', 'red', 'blue' are typical skin names. - * Property type: String. Default value: "default". - */ -#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ - "IMPORT_MD3_SKIN_NAME" - -// --------------------------------------------------------------------------- -/** @brief Specify the Quake 3 shader file to be used for a particular - * MD3 file. This can also be a search path. - * - * By default Assimp's behaviour is as follows: If a MD3 file - * <tt>any_path/models/any_q3_subdir/model_name/file_name.md3</tt> is - * loaded, the library tries to locate the corresponding shader file in - * <tt>any_path/scripts/model_name.shader</tt>. This property overrides this - * behaviour. It can either specify a full path to the shader to be loaded - * or alternatively the path (relative or absolute) to the directory where - * the shaders for all MD3s to be loaded reside. Assimp attempts to open - * <tt>IMPORT_MD3_SHADER_SRC/model_name.shader</tt> first, <tt>IMPORT_MD3_SHADER_SRC/file_name.shader</tt> - * is the fallback file. Note that IMPORT_MD3_SHADER_SRC should have a terminal (back)slash. - * Property type: String. Default value: n/a. - */ -#define AI_CONFIG_IMPORT_MD3_SHADER_SRC \ - "IMPORT_MD3_SHADER_SRC" - -// --------------------------------------------------------------------------- -/** @brief Configures the LWO loader to load just one layer from the model. - * - * LWO files consist of layers and in some cases it could be useful to load - * only one of them. This property can be either a string - which specifies - * the name of the layer - or an integer - the index of the layer. If the - * property is not set the whole LWO model is loaded. Loading fails if the - * requested layer is not available. The layer index is zero-based and the - * layer name may not be empty.<br> - * Property type: Integer. Default value: all layers are loaded. - */ -#define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY \ - "IMPORT_LWO_ONE_LAYER_ONLY" - -// --------------------------------------------------------------------------- -/** @brief Configures the MD5 loader to not load the MD5ANIM file for - * a MD5MESH file automatically. - * - * The default strategy is to look for a file with the same name but the - * MD5ANIM extension in the same directory. If it is found, it is loaded - * and combined with the MD5MESH file. This configuration option can be - * used to disable this behaviour. - * - * * Property type: bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD \ - "IMPORT_MD5_NO_ANIM_AUTOLOAD" - -// --------------------------------------------------------------------------- -/** @brief Defines the begin of the time range for which the LWS loader - * evaluates animations and computes aiNodeAnim's. - * - * Assimp provides full conversion of LightWave's envelope system, including - * pre and post conditions. The loader computes linearly subsampled animation - * chanels with the frame rate given in the LWS file. This property defines - * the start time. Note: animation channels are only generated if a node - * has at least one envelope with more tan one key assigned. This property. - * is given in frames, '0' is the first frame. By default, if this property - * is not set, the importer takes the animation start from the input LWS - * file ('FirstFrame' line)<br> - * Property type: Integer. Default value: taken from file. - * - * @see AI_CONFIG_IMPORT_LWS_ANIM_END - end of the imported time range - */ -#define AI_CONFIG_IMPORT_LWS_ANIM_START \ - "IMPORT_LWS_ANIM_START" -#define AI_CONFIG_IMPORT_LWS_ANIM_END \ - "IMPORT_LWS_ANIM_END" - -// --------------------------------------------------------------------------- -/** @brief Defines the output frame rate of the IRR loader. - * - * IRR animations are difficult to convert for Assimp and there will - * always be a loss of quality. This setting defines how many keys per second - * are returned by the converter.<br> - * Property type: integer. Default value: 100 - */ -#define AI_CONFIG_IMPORT_IRR_ANIM_FPS \ - "IMPORT_IRR_ANIM_FPS" - -// --------------------------------------------------------------------------- -/** @brief Ogre Importer will try to find referenced materials from this file. - * - * Ogre meshes reference with material names, this does not tell Assimp the file - * where it is located in. Assimp will try to find the source file in the following - * order: <material-name>.material, <mesh-filename-base>.material and - * lastly the material name defined by this config property. - * <br> - * Property type: String. Default value: Scene.material. - */ -#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE \ - "IMPORT_OGRE_MATERIAL_FILE" - -// --------------------------------------------------------------------------- -/** @brief Ogre Importer detect the texture usage from its filename. - * - * Ogre material texture units do not define texture type, the textures usage - * depends on the used shader or Ogre's fixed pipeline. If this config property - * is true Assimp will try to detect the type from the textures filename postfix: - * _n, _nrm, _nrml, _normal, _normals and _normalmap for normal map, _s, _spec, - * _specular and _specularmap for specular map, _l, _light, _lightmap, _occ - * and _occlusion for light map, _disp and _displacement for displacement map. - * The matching is case insensitive. Post fix is taken between the last - * underscore and the last period. - * Default behavior is to detect type from lower cased texture unit name by - * matching against: normalmap, specularmap, lightmap and displacementmap. - * For both cases if no match is found aiTextureType_DIFFUSE is used. - * <br> - * Property type: Bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME \ - "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME" - - /** @brief Specifies whether the Android JNI asset extraction is supported. - * - * Turn on this option if you want to manage assets in native - * Android application without having to keep the internal directory and asset - * manager pointer. - */ - #define AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT "AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the IFC loader skips over IfcSpace elements. - * - * IfcSpace elements (and their geometric representations) are used to - * represent, well, free space in a building storey.<br> - * Property type: Bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the IFC loader will use its own, custom triangulation - * algorithm to triangulate wall and floor meshes. - * - * If this property is set to false, walls will be either triangulated by - * #aiProcess_Triangulate or will be passed through as huge polygons with - * faked holes (i.e. holes that are connected with the outer boundary using - * a dummy edge). It is highly recommended to set this property to true - * if you want triangulated data because #aiProcess_Triangulate is known to - * have problems with the kind of polygons that the IFC loader spits out for - * complicated meshes. - * Property type: Bool. Default value: true. - */ -#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION" - -// --------------------------------------------------------------------------- -/** @brief Set the tessellation conic angle for IFC smoothing curves. - * - * This is used by the IFC importer to determine the tessellation parameter - * for smoothing curves. - * @note The default value is AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE and the - * accepted values are in range [5.0, 120.0]. - * Property type: Float. - */ -#define AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE "IMPORT_IFC_SMOOTHING_ANGLE" - -// default value for AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE -#if (!defined AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE) -# define AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE 10.0f -#endif - -// --------------------------------------------------------------------------- -/** @brief Set the tessellation for IFC cylindrical shapes. - * - * This is used by the IFC importer to determine the tessellation parameter - * for cylindrical shapes, i.e. the number of segments used to approximate a circle. - * @note The default value is AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION and the - * accepted values are in range [3, 180]. - * Property type: Integer. - */ -#define AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION "IMPORT_IFC_CYLINDRICAL_TESSELLATION" - -// default value for AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION -#if (!defined AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION) -# define AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION 32 -#endif - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the Collada loader will ignore the provided up direction. - * - * If this property is set to true, the up direction provided in the file header will - * be ignored and the file will be loaded as is. - * Property type: Bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION" - -// --------------------------------------------------------------------------- -/** @brief Specifies whether the Collada loader should use Collada names as node names. - * - * If this property is set to true, the Collada names will be used as the - * node name. The default is to use the id tag (resp. sid tag, if no id tag is present) - * instead. - * Property type: Bool. Default value: false. - */ -#define AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES "IMPORT_COLLADA_USE_COLLADA_NAMES" - -// ---------- All the Export defines ------------ - -/** @brief Specifies the xfile use double for real values of float - * - * Property type: Bool. Default value: false. - */ - -#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT" - -/** @brief Specifies whether the assimp export shall be able to export point clouds - * - * When this flag is not defined the render data has to contain valid faces. - * Point clouds are only a collection of vertices which have nor spatial organization - * by a face and the validation process will remove them. Enabling this feature will - * switch off the flag and enable the functionality to export pure point clouds. - */ -#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS" - -/** - * @brief Specifies a gobal key factor for scale, float value - */ -#define AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY "GLOBAL_SCALE_FACTOR" - -#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT) -# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f -#endif // !! AI_DEBONE_THRESHOLD - -#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR" - -#if (!defined AI_CONFIG_APP_SCALE_KEY) -# define AI_CONFIG_APP_SCALE_KEY 1.0 -#endif // AI_CONFIG_APP_SCALE_KEY - - -// ---------- All the Build/Compile-time defines ------------ - -/** @brief Specifies if double precision is supported inside assimp - * - * Property type: Bool. Default value: undefined. - */ - -#cmakedefine ASSIMP_DOUBLE_PRECISION 1 - -#endif // !! AI_CONFIG_H_INC diff --git a/thirdparty/assimp/include/assimp/defs.h b/thirdparty/assimp/include/assimp/defs.h deleted file mode 100644 index 6f2f8ae88b..0000000000 --- a/thirdparty/assimp/include/assimp/defs.h +++ /dev/null @@ -1,327 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file defs.h - * @brief Assimp build configuration setup. See the notes in the comment - * blocks to find out how to customize _your_ Assimp build. - */ - -#pragma once -#ifndef AI_DEFINES_H_INC -#define AI_DEFINES_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/config.h> - -////////////////////////////////////////////////////////////////////////// -/* Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific - * file format loader. The loader is be excluded from the - * build in this case. 'XX' stands for the most common file - * extension of the file format. E.g.: - * ASSIMP_BUILD_NO_X_IMPORTER disables the X loader. - * - * If you're unsure about that, take a look at the implementation of the - * import plugin you wish to disable. You'll find the right define in the - * first lines of the corresponding unit. - * - * Other (mixed) configuration switches are listed here: - * ASSIMP_BUILD_NO_COMPRESSED_X - * - Disable support for compressed X files (zip) - * ASSIMP_BUILD_NO_COMPRESSED_BLEND - * - Disable support for compressed Blender files (zip) - * ASSIMP_BUILD_NO_COMPRESSED_IFC - * - Disable support for IFCZIP files (unzip) - */ -////////////////////////////////////////////////////////////////////////// - -#ifndef ASSIMP_BUILD_NO_COMPRESSED_X -# define ASSIMP_BUILD_NEED_Z_INFLATE -#endif - -#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND -# define ASSIMP_BUILD_NEED_Z_INFLATE -#endif - -#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC -# define ASSIMP_BUILD_NEED_Z_INFLATE -# define ASSIMP_BUILD_NEED_UNZIP -#endif - -#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER -# define ASSIMP_BUILD_NEED_Z_INFLATE -# define ASSIMP_BUILD_NEED_UNZIP -#endif - -////////////////////////////////////////////////////////////////////////// -/* Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific - * post processing step. This is the current list of process names ('XX'): - * CALCTANGENTS - * JOINVERTICES - * TRIANGULATE - * DROPFACENORMALS - * GENFACENORMALS - * GENVERTEXNORMALS - * REMOVEVC - * SPLITLARGEMESHES - * PRETRANSFORMVERTICES - * LIMITBONEWEIGHTS - * VALIDATEDS - * IMPROVECACHELOCALITY - * FIXINFACINGNORMALS - * REMOVE_REDUNDANTMATERIALS - * OPTIMIZEGRAPH - * SORTBYPTYPE - * FINDINVALIDDATA - * TRANSFORMTEXCOORDS - * GENUVCOORDS - * ENTITYMESHBUILDER - * EMBEDTEXTURES - * MAKELEFTHANDED - * FLIPUVS - * FLIPWINDINGORDER - * OPTIMIZEMESHES - * OPTIMIZEANIMS - * OPTIMIZEGRAPH - * GENENTITYMESHES - * FIXTEXTUREPATHS - * GENBOUNDINGBOXES */ -////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -# undef ASSIMP_API - ////////////////////////////////////////////////////////////////////////// - /* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */ - ////////////////////////////////////////////////////////////////////////// -# ifdef ASSIMP_BUILD_DLL_EXPORT -# define ASSIMP_API __declspec(dllexport) -# define ASSIMP_API_WINONLY __declspec(dllexport) - - ////////////////////////////////////////////////////////////////////////// - /* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in - * an external DLL under Windows. Default is static linkage. */ - ////////////////////////////////////////////////////////////////////////// -# elif (defined ASSIMP_DLL) -# define ASSIMP_API __declspec(dllimport) -# define ASSIMP_API_WINONLY __declspec(dllimport) -# else -# define ASSIMP_API -# define ASSIMP_API_WINONLY -# endif -#elif defined(SWIG) - - /* Do nothing, the relevant defines are all in AssimpSwigPort.i */ - -#else -# define ASSIMP_API __attribute__ ((visibility("default"))) -# define ASSIMP_API_WINONLY -#endif - -#ifdef _MSC_VER -# ifdef ASSIMP_BUILD_DLL_EXPORT -# pragma warning (disable : 4251) -# endif - /* Force the compiler to inline a function, if possible - */ -# define AI_FORCE_INLINE __forceinline - - /* Tells the compiler that a function never returns. Used in code analysis - * to skip dead paths (e.g. after an assertion evaluated to false). */ -# define AI_WONT_RETURN __declspec(noreturn) -#elif defined(SWIG) - - /* Do nothing, the relevant defines are all in AssimpSwigPort.i */ - -#else -# define AI_WONT_RETURN -# define AI_FORCE_INLINE inline -#endif // (defined _MSC_VER) - -#ifdef __GNUC__ -# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn)) -#else -# define AI_WONT_RETURN_SUFFIX -#endif // (defined __clang__) - -#ifdef __cplusplus - /* No explicit 'struct' and 'enum' tags for C++, this keeps showing up - * in doxydocs. - */ -# define C_STRUCT -# define C_ENUM -#else - ////////////////////////////////////////////////////////////////////////// - /* To build the documentation, make sure ASSIMP_DOXYGEN_BUILD - * is defined by Doxygen's preprocessor. The corresponding - * entries in the DOXYFILE are: */ - ////////////////////////////////////////////////////////////////////////// -#if 0 - ENABLE_PREPROCESSING = YES - MACRO_EXPANSION = YES - EXPAND_ONLY_PREDEF = YES - SEARCH_INCLUDES = YES - INCLUDE_PATH = - INCLUDE_FILE_PATTERNS = - PREDEFINED = ASSIMP_DOXYGEN_BUILD=1 - EXPAND_AS_DEFINED = C_STRUCT C_ENUM - SKIP_FUNCTION_MACROS = YES -#endif - ////////////////////////////////////////////////////////////////////////// - /* Doxygen gets confused if we use c-struct typedefs to avoid - * the explicit 'struct' notation. This trick here has the same - * effect as the TYPEDEF_HIDES_STRUCT option, but we don't need - * to typedef all structs/enums. */ - ////////////////////////////////////////////////////////////////////////// -# if (defined ASSIMP_DOXYGEN_BUILD) -# define C_STRUCT -# define C_ENUM -# else -# define C_STRUCT struct -# define C_ENUM enum -# endif -#endif - -#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__)) -# error Currently, Borland is unsupported. Feel free to port Assimp. -#endif - - - ////////////////////////////////////////////////////////////////////////// - /* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp - * without threading support. The library doesn't utilize - * threads then and is itself not threadsafe. */ - ////////////////////////////////////////////////////////////////////////// -#ifndef ASSIMP_BUILD_SINGLETHREADED -# define ASSIMP_BUILD_SINGLETHREADED -#endif - -#if defined(_DEBUG) || ! defined(NDEBUG) -# define ASSIMP_BUILD_DEBUG -#endif - - ////////////////////////////////////////////////////////////////////////// - /* Define ASSIMP_DOUBLE_PRECISION to compile assimp - * with double precision support (64-bit). */ - ////////////////////////////////////////////////////////////////////////// - -#ifdef ASSIMP_DOUBLE_PRECISION - typedef double ai_real; - typedef signed long long int ai_int; - typedef unsigned long long int ai_uint; -#ifndef ASSIMP_AI_REAL_TEXT_PRECISION -#define ASSIMP_AI_REAL_TEXT_PRECISION 16 -#endif // ASSIMP_AI_REAL_TEXT_PRECISION -#else // ASSIMP_DOUBLE_PRECISION - typedef float ai_real; - typedef signed int ai_int; - typedef unsigned int ai_uint; -#ifndef ASSIMP_AI_REAL_TEXT_PRECISION -#define ASSIMP_AI_REAL_TEXT_PRECISION 8 -#endif // ASSIMP_AI_REAL_TEXT_PRECISION -#endif // ASSIMP_DOUBLE_PRECISION - - ////////////////////////////////////////////////////////////////////////// - /* Useful constants */ - ////////////////////////////////////////////////////////////////////////// - -/* This is PI. Hi PI. */ -#define AI_MATH_PI (3.141592653589793238462643383279 ) -#define AI_MATH_TWO_PI (AI_MATH_PI * 2.0) -#define AI_MATH_HALF_PI (AI_MATH_PI * 0.5) - -/* And this is to avoid endless casts to float */ -#define AI_MATH_PI_F (3.1415926538f) -#define AI_MATH_TWO_PI_F (AI_MATH_PI_F * 2.0f) -#define AI_MATH_HALF_PI_F (AI_MATH_PI_F * 0.5f) - -/* Tiny macro to convert from radians to degrees and back */ -#define AI_DEG_TO_RAD(x) ((x)*(ai_real)0.0174532925) -#define AI_RAD_TO_DEG(x) ((x)*(ai_real)57.2957795) - -/* Numerical limits */ -static const ai_real ai_epsilon = (ai_real) 0.00001; - -/* Support for big-endian builds */ -#if defined(__BYTE_ORDER__) -# if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -# if !defined(__BIG_ENDIAN__) -# define __BIG_ENDIAN__ -# endif -# else /* little endian */ -# if defined (__BIG_ENDIAN__) -# undef __BIG_ENDIAN__ -# endif -# endif -#endif -#if defined(__BIG_ENDIAN__) -# define AI_BUILD_BIG_ENDIAN -#endif - - -/** - * To avoid running out of memory - * This can be adjusted for specific use cases - * It's NOT a total limit, just a limit for individual allocations - */ -#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type)) - -#ifndef _MSC_VER -# define AI_NO_EXCEPT noexcept -#else -# if (_MSC_VER >= 1915 ) -# define AI_NO_EXCEPT noexcept -# else -# define AI_NO_EXCEPT -# endif -#endif // _MSC_VER - -/** - * Helper macro to set a pointer to NULL in debug builds - */ -#if (defined ASSIMP_BUILD_DEBUG) -# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL; -#else -# define AI_DEBUG_INVALIDATE_PTR(x) -#endif - -#endif // !! AI_DEFINES_H_INC diff --git a/thirdparty/assimp/include/assimp/fast_atof.h b/thirdparty/assimp/include/assimp/fast_atof.h deleted file mode 100644 index 6e9a1bba7a..0000000000 --- a/thirdparty/assimp/include/assimp/fast_atof.h +++ /dev/null @@ -1,377 +0,0 @@ -#pragma once - -// Copyright (C) 2002-2007 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine" and the "irrXML" project. -// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h - -// ------------------------------------------------------------------------------------ -// Original description: (Schrompf) -// Adapted to the ASSIMP library because the builtin atof indeed takes AGES to parse a -// float inside a large string. Before parsing, it does a strlen on the given point. -// Changes: -// 22nd October 08 (Aramis_acg): Added temporary cast to double, added strtoul10_64 -// to ensure long numbers are handled correctly -// ------------------------------------------------------------------------------------ - -#pragma once -#ifndef FAST_A_TO_F_H_INCLUDED -#define FAST_A_TO_F_H_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <cmath> -#include <limits> -#include <stdint.h> -#include <stdexcept> -#include <assimp/defs.h> - -#include "StringComparison.h" -#include <assimp/DefaultLogger.hpp> - -#ifdef _MSC_VER -# include <stdint.h> -#else -# include <assimp/Compiler/pstdint.h> -#endif - -namespace Assimp { - -const double fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug - 0.0, - 0.1, - 0.01, - 0.001, - 0.0001, - 0.00001, - 0.000001, - 0.0000001, - 0.00000001, - 0.000000001, - 0.0000000001, - 0.00000000001, - 0.000000000001, - 0.0000000000001, - 0.00000000000001, - 0.000000000000001 -}; - - -// ------------------------------------------------------------------------------------ -// Convert a string in decimal format to a number -// ------------------------------------------------------------------------------------ -inline -unsigned int strtoul10( const char* in, const char** out=0) { - unsigned int value = 0; - - for ( ;; ) { - if ( *in < '0' || *in > '9' ) { - break; - } - - value = ( value * 10 ) + ( *in - '0' ); - ++in; - } - if ( out ) { - *out = in; - } - return value; -} - -// ------------------------------------------------------------------------------------ -// Convert a string in octal format to a number -// ------------------------------------------------------------------------------------ -inline -unsigned int strtoul8( const char* in, const char** out=0) { - unsigned int value( 0 ); - for ( ;; ) { - if ( *in < '0' || *in > '7' ) { - break; - } - - value = ( value << 3 ) + ( *in - '0' ); - ++in; - } - if ( out ) { - *out = in; - } - return value; -} - -// ------------------------------------------------------------------------------------ -// Convert a string in hex format to a number -// ------------------------------------------------------------------------------------ -inline -unsigned int strtoul16( const char* in, const char** out=0) { - unsigned int value( 0 ); - for ( ;; ) { - if ( *in >= '0' && *in <= '9' ) { - value = ( value << 4u ) + ( *in - '0' ); - } else if (*in >= 'A' && *in <= 'F') { - value = ( value << 4u ) + ( *in - 'A' ) + 10; - } else if (*in >= 'a' && *in <= 'f') { - value = ( value << 4u ) + ( *in - 'a' ) + 10; - } else { - break; - } - ++in; - } - if ( out ) { - *out = in; - } - return value; -} - -// ------------------------------------------------------------------------------------ -// Convert just one hex digit -// Return value is UINT_MAX if the input character is not a hex digit. -// ------------------------------------------------------------------------------------ -inline -unsigned int HexDigitToDecimal(char in) { - unsigned int out( UINT_MAX ); - if ( in >= '0' && in <= '9' ) { - out = in - '0'; - } else if ( in >= 'a' && in <= 'f' ) { - out = 10u + in - 'a'; - } else if ( in >= 'A' && in <= 'F' ) { - out = 10u + in - 'A'; - } - - // return value is UINT_MAX if the input is not a hex digit - return out; -} - -// ------------------------------------------------------------------------------------ -// Convert a hex-encoded octet (2 characters, i.e. df or 1a). -// ------------------------------------------------------------------------------------ -inline -uint8_t HexOctetToDecimal(const char* in) { - return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]); -} - -// ------------------------------------------------------------------------------------ -// signed variant of strtoul10 -// ------------------------------------------------------------------------------------ -inline -int strtol10( const char* in, const char** out=0) { - bool inv = (*in=='-'); - if ( inv || *in == '+' ) { - ++in; - } - - int value = strtoul10(in,out); - if (inv) { - value = -value; - } - return value; -} - -// ------------------------------------------------------------------------------------ -// Parse a C++-like integer literal - hex and oct prefixes. -// 0xNNNN - hex -// 0NNN - oct -// NNN - dec -// ------------------------------------------------------------------------------------ -inline -unsigned int strtoul_cppstyle( const char* in, const char** out=0) { - if ('0' == in[0]) { - return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out); - } - return strtoul10(in, out); -} - -// ------------------------------------------------------------------------------------ -// Special version of the function, providing higher accuracy and safety -// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows. -// ------------------------------------------------------------------------------------ -inline -uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) { - unsigned int cur = 0; - uint64_t value = 0; - - if ( *in < '0' || *in > '9' ) { - throw std::invalid_argument( std::string( "The string \"" ) + in + "\" cannot be converted into a value." ); - } - - for ( ;; ) { - if ( *in < '0' || *in > '9' ) { - break; - } - - const uint64_t new_value = ( value * (uint64_t) 10 ) + ( (uint64_t) ( *in - '0' ) ); - - // numeric overflow, we rely on you - if ( new_value < value ) { - ASSIMP_LOG_WARN_F( "Converting the string \"", in, "\" into a value resulted in overflow." ); - return 0; - } - - value = new_value; - - ++in; - ++cur; - - if (max_inout && *max_inout == cur) { - if (out) { /* skip to end */ - while ( *in >= '0' && *in <= '9' ) { - ++in; - } - *out = in; - } - - return value; - } - } - if ( out ) { - *out = in; - } - - if ( max_inout ) { - *max_inout = cur; - } - - return value; -} - -// ------------------------------------------------------------------------------------ -// signed variant of strtoul10_64 -// ------------------------------------------------------------------------------------ -inline -int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) { - bool inv = (*in == '-'); - if ( inv || *in == '+' ) { - ++in; - } - - int64_t value = strtoul10_64(in, out, max_inout); - if (inv) { - value = -value; - } - return value; -} - -// Number of relevant decimals for floating-point parsing. -#define AI_FAST_ATOF_RELAVANT_DECIMALS 15 - -// ------------------------------------------------------------------------------------ -//! Provides a fast function for converting a string into a float, -//! about 6 times faster than atof in win32. -// If you find any bugs, please send them to me, niko (at) irrlicht3d.org. -// ------------------------------------------------------------------------------------ -template<typename Real> -inline -const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) { - Real f = 0; - - bool inv = (*c == '-'); - if (inv || *c == '+') { - ++c; - } - - if ((c[0] == 'N' || c[0] == 'n') && ASSIMP_strincmp(c, "nan", 3) == 0) { - out = std::numeric_limits<Real>::quiet_NaN(); - c += 3; - return c; - } - - if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inf", 3) == 0) { - out = std::numeric_limits<Real>::infinity(); - if (inv) { - out = -out; - } - c += 3; - if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inity", 5) == 0) { - c += 5; - } - return c; - } - - if (!(c[0] >= '0' && c[0] <= '9') && - !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { - throw std::invalid_argument("Cannot parse string " - "as real number: does not start with digit " - "or decimal point followed by digit."); - } - - if (*c != '.' && (! check_comma || c[0] != ',')) { - f = static_cast<Real>( strtoul10_64 ( c, &c) ); - } - - if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') { - ++c; - - // NOTE: The original implementation is highly inaccurate here. The precision of a single - // IEEE 754 float is not high enough, everything behind the 6th digit tends to be more - // inaccurate than it would need to be. Casting to double seems to solve the problem. - // strtol_64 is used to prevent integer overflow. - - // Another fix: this tends to become 0 for long numbers if we don't limit the maximum - // number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between - // 1 and 15. - unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS; - double pl = static_cast<double>( strtoul10_64 ( c, &c, &diff )); - - pl *= fast_atof_table[diff]; - f += static_cast<Real>( pl ); - } - // For backwards compatibility: eat trailing dots, but not trailing commas. - else if (*c == '.') { - ++c; - } - - // A major 'E' must be allowed. Necessary for proper reading of some DXF files. - // Thanks to Zhao Lei to point out that this if() must be outside the if (*c == '.' ..) - if (*c == 'e' || *c == 'E') { - ++c; - const bool einv = (*c=='-'); - if (einv || *c=='+') { - ++c; - } - - // The reason float constants are used here is that we've seen cases where compilers - // would perform such casts on compile-time constants at runtime, which would be - // bad considering how frequently fast_atoreal_move<float> is called in Assimp. - Real exp = static_cast<Real>( strtoul10_64(c, &c) ); - if (einv) { - exp = -exp; - } - f *= std::pow(static_cast<Real>(10.0), exp); - } - - if (inv) { - f = -f; - } - out = f; - return c; -} - -// ------------------------------------------------------------------------------------ -// The same but more human. -inline -ai_real fast_atof(const char* c) { - ai_real ret(0.0); - fast_atoreal_move<ai_real>(c, ret); - - return ret; -} - -inline -ai_real fast_atof( const char* c, const char** cout) { - ai_real ret(0.0); - *cout = fast_atoreal_move<ai_real>(c, ret); - - return ret; -} - -inline -ai_real fast_atof( const char** inout) { - ai_real ret(0.0); - *inout = fast_atoreal_move<ai_real>(*inout, ret); - - return ret; -} - -} //! namespace Assimp - -#endif // FAST_A_TO_F_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/importerdesc.h b/thirdparty/assimp/include/assimp/importerdesc.h deleted file mode 100644 index 0a6919c1ae..0000000000 --- a/thirdparty/assimp/include/assimp/importerdesc.h +++ /dev/null @@ -1,148 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file importerdesc.h - * @brief #aiImporterFlags, aiImporterDesc implementation. - */ -#pragma once -#ifndef AI_IMPORTER_DESC_H_INC -#define AI_IMPORTER_DESC_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - - -/** Mixed set of flags for #aiImporterDesc, indicating some features - * common to many importers*/ -enum aiImporterFlags { - /** Indicates that there is a textual encoding of the - * file format; and that it is supported.*/ - aiImporterFlags_SupportTextFlavour = 0x1, - - /** Indicates that there is a binary encoding of the - * file format; and that it is supported.*/ - aiImporterFlags_SupportBinaryFlavour = 0x2, - - /** Indicates that there is a compressed encoding of the - * file format; and that it is supported.*/ - aiImporterFlags_SupportCompressedFlavour = 0x4, - - /** Indicates that the importer reads only a very particular - * subset of the file format. This happens commonly for - * declarative or procedural formats which cannot easily - * be mapped to #aiScene */ - aiImporterFlags_LimitedSupport = 0x8, - - /** Indicates that the importer is highly experimental and - * should be used with care. This only happens for trunk - * (i.e. SVN) versions, experimental code is not included - * in releases. */ - aiImporterFlags_Experimental = 0x10 -}; - - -/** Meta information about a particular importer. Importers need to fill - * this structure, but they can freely decide how talkative they are. - * A common use case for loader meta info is a user interface - * in which the user can choose between various import/export file - * formats. Building such an UI by hand means a lot of maintenance - * as importers/exporters are added to Assimp, so it might be useful - * to have a common mechanism to query some rough importer - * characteristics. */ -struct aiImporterDesc { - /** Full name of the importer (i.e. Blender3D importer)*/ - const char* mName; - - /** Original author (left blank if unknown or whole assimp team) */ - const char* mAuthor; - - /** Current maintainer, left blank if the author maintains */ - const char* mMaintainer; - - /** Implementation comments, i.e. unimplemented features*/ - const char* mComments; - - /** These flags indicate some characteristics common to many - importers. */ - unsigned int mFlags; - - /** Minimum format version that can be loaded im major.minor format, - both are set to 0 if there is either no version scheme - or if the loader doesn't care. */ - unsigned int mMinMajor; - unsigned int mMinMinor; - - /** Maximum format version that can be loaded im major.minor format, - both are set to 0 if there is either no version scheme - or if the loader doesn't care. Loaders that expect to be - forward-compatible to potential future format versions should - indicate zero, otherwise they should specify the current - maximum version.*/ - unsigned int mMaxMajor; - unsigned int mMaxMinor; - - /** List of file extensions this importer can handle. - List entries are separated by space characters. - All entries are lower case without a leading dot (i.e. - "xml dae" would be a valid value. Note that multiple - importers may respond to the same file extension - - assimp calls all importers in the order in which they - are registered and each importer gets the opportunity - to load the file until one importer "claims" the file. Apart - from file extension checks, importers typically use - other methods to quickly reject files (i.e. magic - words) so this does not mean that common or generic - file extensions such as XML would be tediously slow. */ - const char* mFileExtensions; -}; - -/** \brief Returns the Importer description for a given extension. - -Will return a NULL-pointer if no assigned importer desc. was found for the given extension - \param extension [in] The extension to look for - \return A pointer showing to the ImporterDesc, \see aiImporterDesc. -*/ -ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImporterDesc( const char *extension ); - -#endif // AI_IMPORTER_DESC_H_INC diff --git a/thirdparty/assimp/include/assimp/light.h b/thirdparty/assimp/include/assimp/light.h deleted file mode 100644 index bdb2368c4f..0000000000 --- a/thirdparty/assimp/include/assimp/light.h +++ /dev/null @@ -1,263 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file light.h - * @brief Defines the aiLight data structure - */ - -#pragma once -#ifndef AI_LIGHT_H_INC -#define AI_LIGHT_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------------- -/** Enumerates all supported types of light sources. - */ -enum aiLightSourceType -{ - aiLightSource_UNDEFINED = 0x0, - - //! A directional light source has a well-defined direction - //! but is infinitely far away. That's quite a good - //! approximation for sun light. - aiLightSource_DIRECTIONAL = 0x1, - - //! A point light source has a well-defined position - //! in space but no direction - it emits light in all - //! directions. A normal bulb is a point light. - aiLightSource_POINT = 0x2, - - //! A spot light source emits light in a specific - //! angle. It has a position and a direction it is pointing to. - //! A good example for a spot light is a light spot in - //! sport arenas. - aiLightSource_SPOT = 0x3, - - //! The generic light level of the world, including the bounces - //! of all other light sources. - //! Typically, there's at most one ambient light in a scene. - //! This light type doesn't have a valid position, direction, or - //! other properties, just a color. - aiLightSource_AMBIENT = 0x4, - - //! An area light is a rectangle with predefined size that uniformly - //! emits light from one of its sides. The position is center of the - //! rectangle and direction is its normal vector. - aiLightSource_AREA = 0x5, - - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. - */ -#ifndef SWIG - _aiLightSource_Force32Bit = INT_MAX -#endif -}; - -// --------------------------------------------------------------------------- -/** Helper structure to describe a light source. - * - * Assimp supports multiple sorts of light sources, including - * directional, point and spot lights. All of them are defined with just - * a single structure and distinguished by their parameters. - * Note - some file formats (such as 3DS, ASE) export a "target point" - - * the point a spot light is looking at (it can even be animated). Assimp - * writes the target point as a subnode of a spotlights's main node, - * called "<spotName>.Target". However, this is just additional information - * then, the transformation tracks of the main node make the - * spot light already point in the right direction. -*/ -struct aiLight -{ - /** The name of the light source. - * - * There must be a node in the scenegraph with the same name. - * This node specifies the position of the light in the scene - * hierarchy and can be animated. - */ - C_STRUCT aiString mName; - - /** The type of the light source. - * - * aiLightSource_UNDEFINED is not a valid value for this member. - */ - C_ENUM aiLightSourceType mType; - - /** Position of the light source in space. Relative to the - * transformation of the node corresponding to the light. - * - * The position is undefined for directional lights. - */ - C_STRUCT aiVector3D mPosition; - - /** Direction of the light source in space. Relative to the - * transformation of the node corresponding to the light. - * - * The direction is undefined for point lights. The vector - * may be normalized, but it needn't. - */ - C_STRUCT aiVector3D mDirection; - - /** Up direction of the light source in space. Relative to the - * transformation of the node corresponding to the light. - * - * The direction is undefined for point lights. The vector - * may be normalized, but it needn't. - */ - C_STRUCT aiVector3D mUp; - - /** Constant light attenuation factor. - * - * The intensity of the light source at a given distance 'd' from - * the light's position is - * @code - * Atten = 1/( att0 + att1 * d + att2 * d*d) - * @endcode - * This member corresponds to the att0 variable in the equation. - * Naturally undefined for directional lights. - */ - float mAttenuationConstant; - - /** Linear light attenuation factor. - * - * The intensity of the light source at a given distance 'd' from - * the light's position is - * @code - * Atten = 1/( att0 + att1 * d + att2 * d*d) - * @endcode - * This member corresponds to the att1 variable in the equation. - * Naturally undefined for directional lights. - */ - float mAttenuationLinear; - - /** Quadratic light attenuation factor. - * - * The intensity of the light source at a given distance 'd' from - * the light's position is - * @code - * Atten = 1/( att0 + att1 * d + att2 * d*d) - * @endcode - * This member corresponds to the att2 variable in the equation. - * Naturally undefined for directional lights. - */ - float mAttenuationQuadratic; - - /** Diffuse color of the light source - * - * The diffuse light color is multiplied with the diffuse - * material color to obtain the final color that contributes - * to the diffuse shading term. - */ - C_STRUCT aiColor3D mColorDiffuse; - - /** Specular color of the light source - * - * The specular light color is multiplied with the specular - * material color to obtain the final color that contributes - * to the specular shading term. - */ - C_STRUCT aiColor3D mColorSpecular; - - /** Ambient color of the light source - * - * The ambient light color is multiplied with the ambient - * material color to obtain the final color that contributes - * to the ambient shading term. Most renderers will ignore - * this value it, is just a remaining of the fixed-function pipeline - * that is still supported by quite many file formats. - */ - C_STRUCT aiColor3D mColorAmbient; - - /** Inner angle of a spot light's light cone. - * - * The spot light has maximum influence on objects inside this - * angle. The angle is given in radians. It is 2PI for point - * lights and undefined for directional lights. - */ - float mAngleInnerCone; - - /** Outer angle of a spot light's light cone. - * - * The spot light does not affect objects outside this angle. - * The angle is given in radians. It is 2PI for point lights and - * undefined for directional lights. The outer angle must be - * greater than or equal to the inner angle. - * It is assumed that the application uses a smooth - * interpolation between the inner and the outer cone of the - * spot light. - */ - float mAngleOuterCone; - - /** Size of area light source. */ - C_STRUCT aiVector2D mSize; - -#ifdef __cplusplus - - aiLight() AI_NO_EXCEPT - : mType (aiLightSource_UNDEFINED) - , mAttenuationConstant (0.f) - , mAttenuationLinear (1.f) - , mAttenuationQuadratic (0.f) - , mAngleInnerCone ((float)AI_MATH_TWO_PI) - , mAngleOuterCone ((float)AI_MATH_TWO_PI) - , mSize (0.f, 0.f) - { - } - -#endif -}; - -#ifdef __cplusplus -} -#endif - - -#endif // !! AI_LIGHT_H_INC diff --git a/thirdparty/assimp/include/assimp/material.h b/thirdparty/assimp/include/assimp/material.h deleted file mode 100644 index 19a7c69709..0000000000 --- a/thirdparty/assimp/include/assimp/material.h +++ /dev/null @@ -1,1604 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file material.h - * @brief Defines the material system of the library - */ -#pragma once -#ifndef AI_MATERIAL_H_INC -#define AI_MATERIAL_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// Name for default materials (2nd is used if meshes have UV coords) -#define AI_DEFAULT_MATERIAL_NAME "DefaultMaterial" - -// --------------------------------------------------------------------------- -/** @brief Defines how the Nth texture of a specific type is combined with - * the result of all previous layers. - * - * Example (left: key, right: value): <br> - * @code - * DiffColor0 - gray - * DiffTextureOp0 - aiTextureOpMultiply - * DiffTexture0 - tex1.png - * DiffTextureOp0 - aiTextureOpAdd - * DiffTexture1 - tex2.png - * @endcode - * Written as equation, the final diffuse term for a specific pixel would be: - * @code - * diffFinal = DiffColor0 * sampleTex(DiffTexture0,UV0) + - * sampleTex(DiffTexture1,UV0) * diffContrib; - * @endcode - * where 'diffContrib' is the intensity of the incoming light for that pixel. - */ -enum aiTextureOp -{ - /** T = T1 * T2 */ - aiTextureOp_Multiply = 0x0, - - /** T = T1 + T2 */ - aiTextureOp_Add = 0x1, - - /** T = T1 - T2 */ - aiTextureOp_Subtract = 0x2, - - /** T = T1 / T2 */ - aiTextureOp_Divide = 0x3, - - /** T = (T1 + T2) - (T1 * T2) */ - aiTextureOp_SmoothAdd = 0x4, - - /** T = T1 + (T2-0.5) */ - aiTextureOp_SignedAdd = 0x5, - - -#ifndef SWIG - _aiTextureOp_Force32Bit = INT_MAX -#endif -}; - -// --------------------------------------------------------------------------- -/** @brief Defines how UV coordinates outside the [0...1] range are handled. - * - * Commonly referred to as 'wrapping mode'. - */ -enum aiTextureMapMode -{ - /** A texture coordinate u|v is translated to u%1|v%1 - */ - aiTextureMapMode_Wrap = 0x0, - - /** Texture coordinates outside [0...1] - * are clamped to the nearest valid value. - */ - aiTextureMapMode_Clamp = 0x1, - - /** If the texture coordinates for a pixel are outside [0...1] - * the texture is not applied to that pixel - */ - aiTextureMapMode_Decal = 0x3, - - /** A texture coordinate u|v becomes u%1|v%1 if (u-(u%1))%2 is zero and - * 1-(u%1)|1-(v%1) otherwise - */ - aiTextureMapMode_Mirror = 0x2, - -#ifndef SWIG - _aiTextureMapMode_Force32Bit = INT_MAX -#endif -}; - -// --------------------------------------------------------------------------- -/** @brief Defines how the mapping coords for a texture are generated. - * - * Real-time applications typically require full UV coordinates, so the use of - * the aiProcess_GenUVCoords step is highly recommended. It generates proper - * UV channels for non-UV mapped objects, as long as an accurate description - * how the mapping should look like (e.g spherical) is given. - * See the #AI_MATKEY_MAPPING property for more details. - */ -enum aiTextureMapping -{ - /** The mapping coordinates are taken from an UV channel. - * - * The #AI_MATKEY_UVWSRC key specifies from which UV channel - * the texture coordinates are to be taken from (remember, - * meshes can have more than one UV channel). - */ - aiTextureMapping_UV = 0x0, - - /** Spherical mapping */ - aiTextureMapping_SPHERE = 0x1, - - /** Cylindrical mapping */ - aiTextureMapping_CYLINDER = 0x2, - - /** Cubic mapping */ - aiTextureMapping_BOX = 0x3, - - /** Planar mapping */ - aiTextureMapping_PLANE = 0x4, - - /** Undefined mapping. Have fun. */ - aiTextureMapping_OTHER = 0x5, - - -#ifndef SWIG - _aiTextureMapping_Force32Bit = INT_MAX -#endif -}; - -// --------------------------------------------------------------------------- -/** @brief Defines the purpose of a texture - * - * This is a very difficult topic. Different 3D packages support different - * kinds of textures. For very common texture types, such as bumpmaps, the - * rendering results depend on implementation details in the rendering - * pipelines of these applications. Assimp loads all texture references from - * the model file and tries to determine which of the predefined texture - * types below is the best choice to match the original use of the texture - * as closely as possible.<br> - * - * In content pipelines you'll usually define how textures have to be handled, - * and the artists working on models have to conform to this specification, - * regardless which 3D tool they're using. - */ -enum aiTextureType -{ - /** Dummy value. - * - * No texture, but the value to be used as 'texture semantic' - * (#aiMaterialProperty::mSemantic) for all material properties - * *not* related to textures. - */ - aiTextureType_NONE = 0, - - /** LEGACY API MATERIALS - * Legacy refers to materials which - * Were originally implemented in the specifications around 2000. - * These must never be removed, as most engines support them. - */ - - /** The texture is combined with the result of the diffuse - * lighting equation. - */ - aiTextureType_DIFFUSE = 1, - - /** The texture is combined with the result of the specular - * lighting equation. - */ - aiTextureType_SPECULAR = 2, - - /** The texture is combined with the result of the ambient - * lighting equation. - */ - aiTextureType_AMBIENT = 3, - - /** The texture is added to the result of the lighting - * calculation. It isn't influenced by incoming light. - */ - aiTextureType_EMISSIVE = 4, - - /** The texture is a height map. - * - * By convention, higher gray-scale values stand for - * higher elevations from the base height. - */ - aiTextureType_HEIGHT = 5, - - /** The texture is a (tangent space) normal-map. - * - * Again, there are several conventions for tangent-space - * normal maps. Assimp does (intentionally) not - * distinguish here. - */ - aiTextureType_NORMALS = 6, - - /** The texture defines the glossiness of the material. - * - * The glossiness is in fact the exponent of the specular - * (phong) lighting equation. Usually there is a conversion - * function defined to map the linear color values in the - * texture to a suitable exponent. Have fun. - */ - aiTextureType_SHININESS = 7, - - /** The texture defines per-pixel opacity. - * - * Usually 'white' means opaque and 'black' means - * 'transparency'. Or quite the opposite. Have fun. - */ - aiTextureType_OPACITY = 8, - - /** Displacement texture - * - * The exact purpose and format is application-dependent. - * Higher color values stand for higher vertex displacements. - */ - aiTextureType_DISPLACEMENT = 9, - - /** Lightmap texture (aka Ambient Occlusion) - * - * Both 'Lightmaps' and dedicated 'ambient occlusion maps' are - * covered by this material property. The texture contains a - * scaling value for the final color value of a pixel. Its - * intensity is not affected by incoming light. - */ - aiTextureType_LIGHTMAP = 10, - - /** Reflection texture - * - * Contains the color of a perfect mirror reflection. - * Rarely used, almost never for real-time applications. - */ - aiTextureType_REFLECTION = 11, - - /** PBR Materials - * PBR definitions from maya and other modelling packages now use this standard. - * This was originally introduced around 2012. - * Support for this is in game engines like Godot, Unreal or Unity3D. - * Modelling packages which use this are very common now. - */ - - aiTextureType_BASE_COLOR = 12, - aiTextureType_NORMAL_CAMERA = 13, - aiTextureType_EMISSION_COLOR = 14, - aiTextureType_METALNESS = 15, - aiTextureType_DIFFUSE_ROUGHNESS = 16, - aiTextureType_AMBIENT_OCCLUSION = 17, - - /** Unknown texture - * - * A texture reference that does not match any of the definitions - * above is considered to be 'unknown'. It is still imported, - * but is excluded from any further post-processing. - */ - aiTextureType_UNKNOWN = 18, - - -#ifndef SWIG - _aiTextureType_Force32Bit = INT_MAX -#endif -}; - -#define AI_TEXTURE_TYPE_MAX aiTextureType_UNKNOWN - -// --------------------------------------------------------------------------- -/** @brief Defines all shading models supported by the library - * - * The list of shading modes has been taken from Blender. - * See Blender documentation for more information. The API does - * not distinguish between "specular" and "diffuse" shaders (thus the - * specular term for diffuse shading models like Oren-Nayar remains - * undefined). <br> - * Again, this value is just a hint. Assimp tries to select the shader whose - * most common implementation matches the original rendering results of the - * 3D modeller which wrote a particular model as closely as possible. - */ -enum aiShadingMode -{ - /** Flat shading. Shading is done on per-face base, - * diffuse only. Also known as 'faceted shading'. - */ - aiShadingMode_Flat = 0x1, - - /** Simple Gouraud shading. - */ - aiShadingMode_Gouraud = 0x2, - - /** Phong-Shading - - */ - aiShadingMode_Phong = 0x3, - - /** Phong-Blinn-Shading - */ - aiShadingMode_Blinn = 0x4, - - /** Toon-Shading per pixel - * - * Also known as 'comic' shader. - */ - aiShadingMode_Toon = 0x5, - - /** OrenNayar-Shading per pixel - * - * Extension to standard Lambertian shading, taking the - * roughness of the material into account - */ - aiShadingMode_OrenNayar = 0x6, - - /** Minnaert-Shading per pixel - * - * Extension to standard Lambertian shading, taking the - * "darkness" of the material into account - */ - aiShadingMode_Minnaert = 0x7, - - /** CookTorrance-Shading per pixel - * - * Special shader for metallic surfaces. - */ - aiShadingMode_CookTorrance = 0x8, - - /** No shading at all. Constant light influence of 1.0. - */ - aiShadingMode_NoShading = 0x9, - - /** Fresnel shading - */ - aiShadingMode_Fresnel = 0xa, - - -#ifndef SWIG - _aiShadingMode_Force32Bit = INT_MAX -#endif -}; - - -// --------------------------------------------------------------------------- -/** @brief Defines some mixed flags for a particular texture. - * - * Usually you'll instruct your cg artists how textures have to look like ... - * and how they will be processed in your application. However, if you use - * Assimp for completely generic loading purposes you might also need to - * process these flags in order to display as many 'unknown' 3D models as - * possible correctly. - * - * This corresponds to the #AI_MATKEY_TEXFLAGS property. -*/ -enum aiTextureFlags -{ - /** The texture's color values have to be inverted (component-wise 1-n) - */ - aiTextureFlags_Invert = 0x1, - - /** Explicit request to the application to process the alpha channel - * of the texture. - * - * Mutually exclusive with #aiTextureFlags_IgnoreAlpha. These - * flags are set if the library can say for sure that the alpha - * channel is used/is not used. If the model format does not - * define this, it is left to the application to decide whether - * the texture alpha channel - if any - is evaluated or not. - */ - aiTextureFlags_UseAlpha = 0x2, - - /** Explicit request to the application to ignore the alpha channel - * of the texture. - * - * Mutually exclusive with #aiTextureFlags_UseAlpha. - */ - aiTextureFlags_IgnoreAlpha = 0x4, - -#ifndef SWIG - _aiTextureFlags_Force32Bit = INT_MAX -#endif -}; - - -// --------------------------------------------------------------------------- -/** @brief Defines alpha-blend flags. - * - * If you're familiar with OpenGL or D3D, these flags aren't new to you. - * They define *how* the final color value of a pixel is computed, basing - * on the previous color at that pixel and the new color value from the - * material. - * The blend formula is: - * @code - * SourceColor * SourceBlend + DestColor * DestBlend - * @endcode - * where DestColor is the previous color in the framebuffer at this - * position and SourceColor is the material color before the transparency - * calculation.<br> - * This corresponds to the #AI_MATKEY_BLEND_FUNC property. -*/ -enum aiBlendMode -{ - /** - * Formula: - * @code - * SourceColor*SourceAlpha + DestColor*(1-SourceAlpha) - * @endcode - */ - aiBlendMode_Default = 0x0, - - /** Additive blending - * - * Formula: - * @code - * SourceColor*1 + DestColor*1 - * @endcode - */ - aiBlendMode_Additive = 0x1, - - // we don't need more for the moment, but we might need them - // in future versions ... - -#ifndef SWIG - _aiBlendMode_Force32Bit = INT_MAX -#endif -}; - - -#include "./Compiler/pushpack1.h" - -// --------------------------------------------------------------------------- -/** @brief Defines how an UV channel is transformed. - * - * This is just a helper structure for the #AI_MATKEY_UVTRANSFORM key. - * See its documentation for more details. - * - * Typically you'll want to build a matrix of this information. However, - * we keep separate scaling/translation/rotation values to make it - * easier to process and optimize UV transformations internally. - */ -struct aiUVTransform -{ - /** Translation on the u and v axes. - * - * The default value is (0|0). - */ - C_STRUCT aiVector2D mTranslation; - - /** Scaling on the u and v axes. - * - * The default value is (1|1). - */ - C_STRUCT aiVector2D mScaling; - - /** Rotation - in counter-clockwise direction. - * - * The rotation angle is specified in radians. The - * rotation center is 0.5f|0.5f. The default value - * 0.f. - */ - ai_real mRotation; - - -#ifdef __cplusplus - aiUVTransform() AI_NO_EXCEPT - : mTranslation (0.0,0.0) - , mScaling (1.0,1.0) - , mRotation (0.0) - { - // nothing to be done here ... - } -#endif - -}; - -#include "./Compiler/poppack1.h" - -//! @cond AI_DOX_INCLUDE_INTERNAL -// --------------------------------------------------------------------------- -/** @brief A very primitive RTTI system for the contents of material - * properties. - */ -enum aiPropertyTypeInfo -{ - /** Array of single-precision (32 Bit) floats - * - * It is possible to use aiGetMaterialInteger[Array]() (or the C++-API - * aiMaterial::Get()) to query properties stored in floating-point format. - * The material system performs the type conversion automatically. - */ - aiPTI_Float = 0x1, - - /** Array of double-precision (64 Bit) floats - * - * It is possible to use aiGetMaterialInteger[Array]() (or the C++-API - * aiMaterial::Get()) to query properties stored in floating-point format. - * The material system performs the type conversion automatically. - */ - aiPTI_Double = 0x2, - - /** The material property is an aiString. - * - * Arrays of strings aren't possible, aiGetMaterialString() (or the - * C++-API aiMaterial::Get()) *must* be used to query a string property. - */ - aiPTI_String = 0x3, - - /** Array of (32 Bit) integers - * - * It is possible to use aiGetMaterialFloat[Array]() (or the C++-API - * aiMaterial::Get()) to query properties stored in integer format. - * The material system performs the type conversion automatically. - */ - aiPTI_Integer = 0x4, - - - /** Simple binary buffer, content undefined. Not convertible to anything. - */ - aiPTI_Buffer = 0x5, - - - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. - */ -#ifndef SWIG - _aiPTI_Force32Bit = INT_MAX -#endif -}; - -// --------------------------------------------------------------------------- -/** @brief Data structure for a single material property - * - * As an user, you'll probably never need to deal with this data structure. - * Just use the provided aiGetMaterialXXX() or aiMaterial::Get() family - * of functions to query material properties easily. Processing them - * manually is faster, but it is not the recommended way. It isn't worth - * the effort. <br> - * Material property names follow a simple scheme: - * @code - * $<name> - * ?<name> - * A public property, there must be corresponding AI_MATKEY_XXX define - * 2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials - * post-processing step. - * ~<name> - * A temporary property for internal use. - * @endcode - * @see aiMaterial - */ -struct aiMaterialProperty -{ - /** Specifies the name of the property (key) - * Keys are generally case insensitive. - */ - C_STRUCT aiString mKey; - - /** Textures: Specifies their exact usage semantic. - * For non-texture properties, this member is always 0 - * (or, better-said, #aiTextureType_NONE). - */ - unsigned int mSemantic; - - /** Textures: Specifies the index of the texture. - * For non-texture properties, this member is always 0. - */ - unsigned int mIndex; - - /** Size of the buffer mData is pointing to, in bytes. - * This value may not be 0. - */ - unsigned int mDataLength; - - /** Type information for the property. - * - * Defines the data layout inside the data buffer. This is used - * by the library internally to perform debug checks and to - * utilize proper type conversions. - * (It's probably a hacky solution, but it works.) - */ - C_ENUM aiPropertyTypeInfo mType; - - /** Binary buffer to hold the property's value. - * The size of the buffer is always mDataLength. - */ - char* mData; - -#ifdef __cplusplus - - aiMaterialProperty() AI_NO_EXCEPT - : mSemantic( 0 ) - , mIndex( 0 ) - , mDataLength( 0 ) - , mType( aiPTI_Float ) - , mData(nullptr) { - // empty - } - - ~aiMaterialProperty() { - delete[] mData; - mData = nullptr; - } - -#endif -}; -//! @endcond - -#ifdef __cplusplus -} // We need to leave the "C" block here to allow template member functions -#endif - -// --------------------------------------------------------------------------- -/** @brief Data structure for a material -* -* Material data is stored using a key-value structure. A single key-value -* pair is called a 'material property'. C++ users should use the provided -* member functions of aiMaterial to process material properties, C users -* have to stick with the aiMaterialGetXXX family of unbound functions. -* The library defines a set of standard keys (AI_MATKEY_XXX). -*/ -#ifdef __cplusplus -struct ASSIMP_API aiMaterial -#else -struct aiMaterial -#endif -{ - -#ifdef __cplusplus - -public: - - aiMaterial(); - ~aiMaterial(); - - // ------------------------------------------------------------------- - /** - * @brief Returns the name of the material. - * @return The name of the material. - */ - // ------------------------------------------------------------------- - aiString GetName(); - - // ------------------------------------------------------------------- - /** @brief Retrieve an array of Type values with a specific key - * from the material - * - * @param pKey Key to search for. One of the AI_MATKEY_XXX constants. - * @param type .. set by AI_MATKEY_XXX - * @param idx .. set by AI_MATKEY_XXX - * @param pOut Pointer to a buffer to receive the result. - * @param pMax Specifies the size of the given buffer, in Type's. - * Receives the number of values (not bytes!) read. - * NULL is a valid value for this parameter. - */ - template <typename Type> - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, Type* pOut, unsigned int* pMax) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, int* pOut, unsigned int* pMax) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, ai_real* pOut, unsigned int* pMax) const; - - // ------------------------------------------------------------------- - /** @brief Retrieve a Type value with a specific key - * from the material - * - * @param pKey Key to search for. One of the AI_MATKEY_XXX constants. - * @param type Specifies the type of the texture to be retrieved ( - * e.g. diffuse, specular, height map ...) - * @param idx Index of the texture to be retrieved. - * @param pOut Reference to receive the output value - */ - template <typename Type> - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx,Type& pOut) const; - - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, int& pOut) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, ai_real& pOut) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, aiString& pOut) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, aiColor3D& pOut) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, aiColor4D& pOut) const; - - aiReturn Get(const char* pKey,unsigned int type, - unsigned int idx, aiUVTransform& pOut) const; - - // ------------------------------------------------------------------- - /** Get the number of textures for a particular texture type. - * @param type Texture type to check for - * @return Number of textures for this type. - * @note A texture can be easily queried using #GetTexture() */ - unsigned int GetTextureCount(aiTextureType type) const; - - // ------------------------------------------------------------------- - /** Helper function to get all parameters pertaining to a - * particular texture slot from a material. - * - * This function is provided just for convenience, you could also - * read the single material properties manually. - * @param type Specifies the type of the texture to be retrieved ( - * e.g. diffuse, specular, height map ...) - * @param index Index of the texture to be retrieved. The function fails - * if there is no texture of that type with this index. - * #GetTextureCount() can be used to determine the number of textures - * per texture type. - * @param path Receives the path to the texture. - * If the texture is embedded, receives a '*' followed by the id of - * the texture (for the textures stored in the corresponding scene) which - * can be converted to an int using a function like atoi. - * NULL is a valid value. - * @param mapping The texture mapping. - * NULL is allowed as value. - * @param uvindex Receives the UV index of the texture. - * NULL is a valid value. - * @param blend Receives the blend factor for the texture - * NULL is a valid value. - * @param op Receives the texture operation to be performed between - * this texture and the previous texture. NULL is allowed as value. - * @param mapmode Receives the mapping modes to be used for the texture. - * The parameter may be NULL but if it is a valid pointer it MUST - * point to an array of 3 aiTextureMapMode's (one for each - * axis: UVW order (=XYZ)). - */ - // ------------------------------------------------------------------- - aiReturn GetTexture(aiTextureType type, - unsigned int index, - C_STRUCT aiString* path, - aiTextureMapping* mapping = NULL, - unsigned int* uvindex = NULL, - ai_real* blend = NULL, - aiTextureOp* op = NULL, - aiTextureMapMode* mapmode = NULL) const; - - - // Setters - - - // ------------------------------------------------------------------------------ - /** @brief Add a property with a given key and type info to the material - * structure - * - * @param pInput Pointer to input data - * @param pSizeInBytes Size of input data - * @param pKey Key/Usage of the property (AI_MATKEY_XXX) - * @param type Set by the AI_MATKEY_XXX macro - * @param index Set by the AI_MATKEY_XXX macro - * @param pType Type information hint */ - aiReturn AddBinaryProperty (const void* pInput, - unsigned int pSizeInBytes, - const char* pKey, - unsigned int type , - unsigned int index , - aiPropertyTypeInfo pType); - - // ------------------------------------------------------------------------------ - /** @brief Add a string property with a given key and type info to the - * material structure - * - * @param pInput Input string - * @param pKey Key/Usage of the property (AI_MATKEY_XXX) - * @param type Set by the AI_MATKEY_XXX macro - * @param index Set by the AI_MATKEY_XXX macro */ - aiReturn AddProperty (const aiString* pInput, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - // ------------------------------------------------------------------------------ - /** @brief Add a property with a given key to the material structure - * @param pInput Pointer to the input data - * @param pNumValues Number of values in the array - * @param pKey Key/Usage of the property (AI_MATKEY_XXX) - * @param type Set by the AI_MATKEY_XXX macro - * @param index Set by the AI_MATKEY_XXX macro */ - template<class TYPE> - aiReturn AddProperty (const TYPE* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const aiVector3D* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const aiColor3D* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const aiColor4D* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const int* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const float* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const double* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - aiReturn AddProperty (const aiUVTransform* pInput, - unsigned int pNumValues, - const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - // ------------------------------------------------------------------------------ - /** @brief Remove a given key from the list. - * - * The function fails if the key isn't found - * @param pKey Key to be deleted - * @param type Set by the AI_MATKEY_XXX macro - * @param index Set by the AI_MATKEY_XXX macro */ - aiReturn RemoveProperty (const char* pKey, - unsigned int type = 0, - unsigned int index = 0); - - // ------------------------------------------------------------------------------ - /** @brief Removes all properties from the material. - * - * The data array remains allocated so adding new properties is quite fast. */ - void Clear(); - - // ------------------------------------------------------------------------------ - /** Copy the property list of a material - * @param pcDest Destination material - * @param pcSrc Source material - */ - static void CopyPropertyList(aiMaterial* pcDest, - const aiMaterial* pcSrc); - - -#endif - - /** List of all material properties loaded. */ - C_STRUCT aiMaterialProperty** mProperties; - - /** Number of properties in the data base */ - unsigned int mNumProperties; - - /** Storage allocated */ - unsigned int mNumAllocated; -}; - -// Go back to extern "C" again -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------------- -#define AI_MATKEY_NAME "?mat.name",0,0 -#define AI_MATKEY_TWOSIDED "$mat.twosided",0,0 -#define AI_MATKEY_SHADING_MODEL "$mat.shadingm",0,0 -#define AI_MATKEY_ENABLE_WIREFRAME "$mat.wireframe",0,0 -#define AI_MATKEY_BLEND_FUNC "$mat.blend",0,0 -#define AI_MATKEY_OPACITY "$mat.opacity",0,0 -#define AI_MATKEY_TRANSPARENCYFACTOR "$mat.transparencyfactor",0,0 -#define AI_MATKEY_BUMPSCALING "$mat.bumpscaling",0,0 -#define AI_MATKEY_SHININESS "$mat.shininess",0,0 -#define AI_MATKEY_REFLECTIVITY "$mat.reflectivity",0,0 -#define AI_MATKEY_SHININESS_STRENGTH "$mat.shinpercent",0,0 -#define AI_MATKEY_REFRACTI "$mat.refracti",0,0 -#define AI_MATKEY_COLOR_DIFFUSE "$clr.diffuse",0,0 -#define AI_MATKEY_COLOR_AMBIENT "$clr.ambient",0,0 -#define AI_MATKEY_COLOR_SPECULAR "$clr.specular",0,0 -#define AI_MATKEY_COLOR_EMISSIVE "$clr.emissive",0,0 -#define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0 -#define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0 -#define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "?bg.global",0,0 -#define AI_MATKEY_GLOBAL_SHADERLANG "?sh.lang",0,0 -#define AI_MATKEY_SHADER_VERTEX "?sh.vs",0,0 -#define AI_MATKEY_SHADER_FRAGMENT "?sh.fs",0,0 -#define AI_MATKEY_SHADER_GEO "?sh.gs",0,0 -#define AI_MATKEY_SHADER_TESSELATION "?sh.ts",0,0 -#define AI_MATKEY_SHADER_PRIMITIVE "?sh.ps",0,0 -#define AI_MATKEY_SHADER_COMPUTE "?sh.cs",0,0 - -// --------------------------------------------------------------------------- -// Pure key names for all texture-related properties -//! @cond MATS_DOC_FULL -#define _AI_MATKEY_TEXTURE_BASE "$tex.file" -#define _AI_MATKEY_UVWSRC_BASE "$tex.uvwsrc" -#define _AI_MATKEY_TEXOP_BASE "$tex.op" -#define _AI_MATKEY_MAPPING_BASE "$tex.mapping" -#define _AI_MATKEY_TEXBLEND_BASE "$tex.blend" -#define _AI_MATKEY_MAPPINGMODE_U_BASE "$tex.mapmodeu" -#define _AI_MATKEY_MAPPINGMODE_V_BASE "$tex.mapmodev" -#define _AI_MATKEY_TEXMAP_AXIS_BASE "$tex.mapaxis" -#define _AI_MATKEY_UVTRANSFORM_BASE "$tex.uvtrafo" -#define _AI_MATKEY_TEXFLAGS_BASE "$tex.flags" -//! @endcond - -// --------------------------------------------------------------------------- -#define AI_MATKEY_TEXTURE(type, N) _AI_MATKEY_TEXTURE_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_TEXTURE_DIFFUSE(N) \ - AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_TEXTURE_SPECULAR(N) \ - AI_MATKEY_TEXTURE(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_TEXTURE_AMBIENT(N) \ - AI_MATKEY_TEXTURE(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_TEXTURE_EMISSIVE(N) \ - AI_MATKEY_TEXTURE(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_TEXTURE_NORMALS(N) \ - AI_MATKEY_TEXTURE(aiTextureType_NORMALS,N) - -#define AI_MATKEY_TEXTURE_HEIGHT(N) \ - AI_MATKEY_TEXTURE(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_TEXTURE_SHININESS(N) \ - AI_MATKEY_TEXTURE(aiTextureType_SHININESS,N) - -#define AI_MATKEY_TEXTURE_OPACITY(N) \ - AI_MATKEY_TEXTURE(aiTextureType_OPACITY,N) - -#define AI_MATKEY_TEXTURE_DISPLACEMENT(N) \ - AI_MATKEY_TEXTURE(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_TEXTURE_LIGHTMAP(N) \ - AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_TEXTURE_REFLECTION(N) \ - AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,N) - -//! @endcond - -// --------------------------------------------------------------------------- -#define AI_MATKEY_UVWSRC(type, N) _AI_MATKEY_UVWSRC_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_UVWSRC_DIFFUSE(N) \ - AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_UVWSRC_SPECULAR(N) \ - AI_MATKEY_UVWSRC(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_UVWSRC_AMBIENT(N) \ - AI_MATKEY_UVWSRC(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_UVWSRC_EMISSIVE(N) \ - AI_MATKEY_UVWSRC(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_UVWSRC_NORMALS(N) \ - AI_MATKEY_UVWSRC(aiTextureType_NORMALS,N) - -#define AI_MATKEY_UVWSRC_HEIGHT(N) \ - AI_MATKEY_UVWSRC(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_UVWSRC_SHININESS(N) \ - AI_MATKEY_UVWSRC(aiTextureType_SHININESS,N) - -#define AI_MATKEY_UVWSRC_OPACITY(N) \ - AI_MATKEY_UVWSRC(aiTextureType_OPACITY,N) - -#define AI_MATKEY_UVWSRC_DISPLACEMENT(N) \ - AI_MATKEY_UVWSRC(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_UVWSRC_LIGHTMAP(N) \ - AI_MATKEY_UVWSRC(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_UVWSRC_REFLECTION(N) \ - AI_MATKEY_UVWSRC(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_TEXOP(type, N) _AI_MATKEY_TEXOP_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_TEXOP_DIFFUSE(N) \ - AI_MATKEY_TEXOP(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_TEXOP_SPECULAR(N) \ - AI_MATKEY_TEXOP(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_TEXOP_AMBIENT(N) \ - AI_MATKEY_TEXOP(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_TEXOP_EMISSIVE(N) \ - AI_MATKEY_TEXOP(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_TEXOP_NORMALS(N) \ - AI_MATKEY_TEXOP(aiTextureType_NORMALS,N) - -#define AI_MATKEY_TEXOP_HEIGHT(N) \ - AI_MATKEY_TEXOP(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_TEXOP_SHININESS(N) \ - AI_MATKEY_TEXOP(aiTextureType_SHININESS,N) - -#define AI_MATKEY_TEXOP_OPACITY(N) \ - AI_MATKEY_TEXOP(aiTextureType_OPACITY,N) - -#define AI_MATKEY_TEXOP_DISPLACEMENT(N) \ - AI_MATKEY_TEXOP(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_TEXOP_LIGHTMAP(N) \ - AI_MATKEY_TEXOP(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_TEXOP_REFLECTION(N) \ - AI_MATKEY_TEXOP(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_MAPPING(type, N) _AI_MATKEY_MAPPING_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_MAPPING_DIFFUSE(N) \ - AI_MATKEY_MAPPING(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_MAPPING_SPECULAR(N) \ - AI_MATKEY_MAPPING(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_MAPPING_AMBIENT(N) \ - AI_MATKEY_MAPPING(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_MAPPING_EMISSIVE(N) \ - AI_MATKEY_MAPPING(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_MAPPING_NORMALS(N) \ - AI_MATKEY_MAPPING(aiTextureType_NORMALS,N) - -#define AI_MATKEY_MAPPING_HEIGHT(N) \ - AI_MATKEY_MAPPING(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_MAPPING_SHININESS(N) \ - AI_MATKEY_MAPPING(aiTextureType_SHININESS,N) - -#define AI_MATKEY_MAPPING_OPACITY(N) \ - AI_MATKEY_MAPPING(aiTextureType_OPACITY,N) - -#define AI_MATKEY_MAPPING_DISPLACEMENT(N) \ - AI_MATKEY_MAPPING(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_MAPPING_LIGHTMAP(N) \ - AI_MATKEY_MAPPING(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_MAPPING_REFLECTION(N) \ - AI_MATKEY_MAPPING(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_TEXBLEND(type, N) _AI_MATKEY_TEXBLEND_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_TEXBLEND_DIFFUSE(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_TEXBLEND_SPECULAR(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_TEXBLEND_AMBIENT(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_TEXBLEND_EMISSIVE(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_TEXBLEND_NORMALS(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_NORMALS,N) - -#define AI_MATKEY_TEXBLEND_HEIGHT(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_TEXBLEND_SHININESS(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_SHININESS,N) - -#define AI_MATKEY_TEXBLEND_OPACITY(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_OPACITY,N) - -#define AI_MATKEY_TEXBLEND_DISPLACEMENT(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_TEXBLEND_LIGHTMAP(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_TEXBLEND_REFLECTION(N) \ - AI_MATKEY_TEXBLEND(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_MAPPINGMODE_U(type, N) _AI_MATKEY_MAPPINGMODE_U_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_MAPPINGMODE_U_DIFFUSE(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_MAPPINGMODE_U_SPECULAR(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_MAPPINGMODE_U_AMBIENT(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_MAPPINGMODE_U_EMISSIVE(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_MAPPINGMODE_U_NORMALS(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_NORMALS,N) - -#define AI_MATKEY_MAPPINGMODE_U_HEIGHT(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_MAPPINGMODE_U_SHININESS(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_SHININESS,N) - -#define AI_MATKEY_MAPPINGMODE_U_OPACITY(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_OPACITY,N) - -#define AI_MATKEY_MAPPINGMODE_U_DISPLACEMENT(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_MAPPINGMODE_U_REFLECTION(N) \ - AI_MATKEY_MAPPINGMODE_U(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_MAPPINGMODE_V(type, N) _AI_MATKEY_MAPPINGMODE_V_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_MAPPINGMODE_V_DIFFUSE(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_MAPPINGMODE_V_SPECULAR(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_MAPPINGMODE_V_AMBIENT(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_MAPPINGMODE_V_EMISSIVE(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_MAPPINGMODE_V_NORMALS(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_NORMALS,N) - -#define AI_MATKEY_MAPPINGMODE_V_HEIGHT(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_MAPPINGMODE_V_SHININESS(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_SHININESS,N) - -#define AI_MATKEY_MAPPINGMODE_V_OPACITY(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_OPACITY,N) - -#define AI_MATKEY_MAPPINGMODE_V_DISPLACEMENT(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_MAPPINGMODE_V_REFLECTION(N) \ - AI_MATKEY_MAPPINGMODE_V(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_TEXMAP_AXIS(type, N) _AI_MATKEY_TEXMAP_AXIS_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_TEXMAP_AXIS_DIFFUSE(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_TEXMAP_AXIS_SPECULAR(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_TEXMAP_AXIS_AMBIENT(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_TEXMAP_AXIS_EMISSIVE(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_TEXMAP_AXIS_NORMALS(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_NORMALS,N) - -#define AI_MATKEY_TEXMAP_AXIS_HEIGHT(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_TEXMAP_AXIS_SHININESS(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_SHININESS,N) - -#define AI_MATKEY_TEXMAP_AXIS_OPACITY(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_OPACITY,N) - -#define AI_MATKEY_TEXMAP_AXIS_DISPLACEMENT(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_TEXMAP_AXIS_LIGHTMAP(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_TEXMAP_AXIS_REFLECTION(N) \ - AI_MATKEY_TEXMAP_AXIS(aiTextureType_REFLECTION,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_UVTRANSFORM(type, N) _AI_MATKEY_UVTRANSFORM_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_UVTRANSFORM_DIFFUSE(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_UVTRANSFORM_SPECULAR(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_UVTRANSFORM_AMBIENT(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_UVTRANSFORM_EMISSIVE(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_UVTRANSFORM_NORMALS(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_NORMALS,N) - -#define AI_MATKEY_UVTRANSFORM_HEIGHT(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_UVTRANSFORM_SHININESS(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_SHININESS,N) - -#define AI_MATKEY_UVTRANSFORM_OPACITY(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_OPACITY,N) - -#define AI_MATKEY_UVTRANSFORM_DISPLACEMENT(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_UVTRANSFORM_LIGHTMAP(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_UVTRANSFORM_REFLECTION(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_REFLECTION,N) - -#define AI_MATKEY_UVTRANSFORM_UNKNOWN(N) \ - AI_MATKEY_UVTRANSFORM(aiTextureType_UNKNOWN,N) - -//! @endcond -// --------------------------------------------------------------------------- -#define AI_MATKEY_TEXFLAGS(type, N) _AI_MATKEY_TEXFLAGS_BASE,type,N - -// For backward compatibility and simplicity -//! @cond MATS_DOC_FULL -#define AI_MATKEY_TEXFLAGS_DIFFUSE(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_TEXFLAGS_SPECULAR(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_TEXFLAGS_AMBIENT(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_TEXFLAGS_EMISSIVE(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_TEXFLAGS_NORMALS(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_NORMALS,N) - -#define AI_MATKEY_TEXFLAGS_HEIGHT(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_TEXFLAGS_SHININESS(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_SHININESS,N) - -#define AI_MATKEY_TEXFLAGS_OPACITY(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_OPACITY,N) - -#define AI_MATKEY_TEXFLAGS_DISPLACEMENT(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_DISPLACEMENT,N) - -#define AI_MATKEY_TEXFLAGS_LIGHTMAP(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_LIGHTMAP,N) - -#define AI_MATKEY_TEXFLAGS_REFLECTION(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_REFLECTION,N) - -#define AI_MATKEY_TEXFLAGS_UNKNOWN(N) \ - AI_MATKEY_TEXFLAGS(aiTextureType_UNKNOWN,N) - -//! @endcond -//! -// --------------------------------------------------------------------------- -/** @brief Retrieve a material property with a specific key from the material - * - * @param pMat Pointer to the input material. May not be NULL - * @param pKey Key to search for. One of the AI_MATKEY_XXX constants. - * @param type Specifies the type of the texture to be retrieved ( - * e.g. diffuse, specular, height map ...) - * @param index Index of the texture to be retrieved. - * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty - * structure or NULL if the key has not been found. */ -// --------------------------------------------------------------------------- -ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty( - const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - const C_STRUCT aiMaterialProperty** pPropOut); - -// --------------------------------------------------------------------------- -/** @brief Retrieve an array of float values with a specific key - * from the material - * - * Pass one of the AI_MATKEY_XXX constants for the last three parameters (the - * example reads the #AI_MATKEY_UVTRANSFORM property of the first diffuse texture) - * @code - * aiUVTransform trafo; - * unsigned int max = sizeof(aiUVTransform); - * if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0), - * (float*)&trafo, &max) || sizeof(aiUVTransform) != max) - * { - * // error handling - * } - * @endcode - * - * @param pMat Pointer to the input material. May not be NULL - * @param pKey Key to search for. One of the AI_MATKEY_XXX constants. - * @param pOut Pointer to a buffer to receive the result. - * @param pMax Specifies the size of the given buffer, in float's. - * Receives the number of values (not bytes!) read. - * @param type (see the code sample above) - * @param index (see the code sample above) - * @return Specifies whether the key has been found. If not, the output - * arrays remains unmodified and pMax is set to 0.*/ -// --------------------------------------------------------------------------- -ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray( - const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - ai_real* pOut, - unsigned int* pMax); - - -#ifdef __cplusplus - -// --------------------------------------------------------------------------- -/** @brief Retrieve a single float property with a specific key from the material. -* -* Pass one of the AI_MATKEY_XXX constants for the last three parameters (the -* example reads the #AI_MATKEY_SHININESS_STRENGTH property of the first diffuse texture) -* @code -* float specStrength = 1.f; // default value, remains unmodified if we fail. -* aiGetMaterialFloat(mat, AI_MATKEY_SHININESS_STRENGTH, -* (float*)&specStrength); -* @endcode -* -* @param pMat Pointer to the input material. May not be NULL -* @param pKey Key to search for. One of the AI_MATKEY_XXX constants. -* @param pOut Receives the output float. -* @param type (see the code sample above) -* @param index (see the code sample above) -* @return Specifies whether the key has been found. If not, the output -* float remains unmodified.*/ -// --------------------------------------------------------------------------- -inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - ai_real* pOut) -{ - return aiGetMaterialFloatArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0); -} - -#else - -// Use our friend, the C preprocessor -#define aiGetMaterialFloat (pMat, type, index, pKey, pOut) \ - aiGetMaterialFloatArray(pMat, type, index, pKey, pOut, NULL) - -#endif //!__cplusplus - - -// --------------------------------------------------------------------------- -/** @brief Retrieve an array of integer values with a specific key - * from a material - * - * See the sample for aiGetMaterialFloatArray for more information.*/ -ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - int* pOut, - unsigned int* pMax); - - -#ifdef __cplusplus - -// --------------------------------------------------------------------------- -/** @brief Retrieve an integer property with a specific key from a material - * - * See the sample for aiGetMaterialFloat for more information.*/ -// --------------------------------------------------------------------------- -inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - int* pOut) -{ - return aiGetMaterialIntegerArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0); -} - -#else - -// use our friend, the C preprocessor -#define aiGetMaterialInteger (pMat, type, index, pKey, pOut) \ - aiGetMaterialIntegerArray(pMat, type, index, pKey, pOut, NULL) - -#endif //!__cplusplus - -// --------------------------------------------------------------------------- -/** @brief Retrieve a color value from the material property table -* -* See the sample for aiGetMaterialFloat for more information*/ -// --------------------------------------------------------------------------- -ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - C_STRUCT aiColor4D* pOut); - - -// --------------------------------------------------------------------------- -/** @brief Retrieve a aiUVTransform value from the material property table -* -* See the sample for aiGetMaterialFloat for more information*/ -// --------------------------------------------------------------------------- -ASSIMP_API C_ENUM aiReturn aiGetMaterialUVTransform(const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - C_STRUCT aiUVTransform* pOut); - - -// --------------------------------------------------------------------------- -/** @brief Retrieve a string from the material property table -* -* See the sample for aiGetMaterialFloat for more information.*/ -// --------------------------------------------------------------------------- -ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat, - const char* pKey, - unsigned int type, - unsigned int index, - C_STRUCT aiString* pOut); - -// --------------------------------------------------------------------------- -/** Get the number of textures for a particular texture type. - * @param[in] pMat Pointer to the input material. May not be NULL - * @param type Texture type to check for - * @return Number of textures for this type. - * @note A texture can be easily queried using #aiGetMaterialTexture() */ -// --------------------------------------------------------------------------- -ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat, - C_ENUM aiTextureType type); - -// --------------------------------------------------------------------------- -/** @brief Helper function to get all values pertaining to a particular - * texture slot from a material structure. - * - * This function is provided just for convenience. You could also read the - * texture by parsing all of its properties manually. This function bundles - * all of them in a huge function monster. - * - * @param[in] mat Pointer to the input material. May not be NULL - * @param[in] type Specifies the texture stack to read from (e.g. diffuse, - * specular, height map ...). - * @param[in] index Index of the texture. The function fails if the - * requested index is not available for this texture type. - * #aiGetMaterialTextureCount() can be used to determine the number of - * textures in a particular texture stack. - * @param[out] path Receives the output path - * If the texture is embedded, receives a '*' followed by the id of - * the texture (for the textures stored in the corresponding scene) which - * can be converted to an int using a function like atoi. - * This parameter must be non-null. - * @param mapping The texture mapping mode to be used. - * Pass NULL if you're not interested in this information. - * @param[out] uvindex For UV-mapped textures: receives the index of the UV - * source channel. Unmodified otherwise. - * Pass NULL if you're not interested in this information. - * @param[out] blend Receives the blend factor for the texture - * Pass NULL if you're not interested in this information. - * @param[out] op Receives the texture blend operation to be perform between - * this texture and the previous texture. - * Pass NULL if you're not interested in this information. - * @param[out] mapmode Receives the mapping modes to be used for the texture. - * Pass NULL if you're not interested in this information. Otherwise, - * pass a pointer to an array of two aiTextureMapMode's (one for each - * axis, UV order). - * @param[out] flags Receives the the texture flags. - * @return AI_SUCCESS on success, otherwise something else. Have fun.*/ -// --------------------------------------------------------------------------- -#ifdef __cplusplus -ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, - aiTextureType type, - unsigned int index, - aiString* path, - aiTextureMapping* mapping = NULL, - unsigned int* uvindex = NULL, - ai_real* blend = NULL, - aiTextureOp* op = NULL, - aiTextureMapMode* mapmode = NULL, - unsigned int* flags = NULL); -#else -C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, - C_ENUM aiTextureType type, - unsigned int index, - C_STRUCT aiString* path, - C_ENUM aiTextureMapping* mapping /*= NULL*/, - unsigned int* uvindex /*= NULL*/, - ai_real* blend /*= NULL*/, - C_ENUM aiTextureOp* op /*= NULL*/, - C_ENUM aiTextureMapMode* mapmode /*= NULL*/, - unsigned int* flags /*= NULL*/); -#endif // !#ifdef __cplusplus - - -#ifdef __cplusplus -} - -#include "material.inl" - -#endif //!__cplusplus - -#endif //!!AI_MATERIAL_H_INC diff --git a/thirdparty/assimp/include/assimp/material.inl b/thirdparty/assimp/include/assimp/material.inl deleted file mode 100644 index 8ae6b88d3e..0000000000 --- a/thirdparty/assimp/include/assimp/material.inl +++ /dev/null @@ -1,389 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file material.inl - * @brief Defines the C++ getters for the material system - */ - -#pragma once -#ifndef AI_MATERIAL_INL_INC -#define AI_MATERIAL_INL_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiPropertyTypeInfo ai_real_to_property_type_info(float) { - return aiPTI_Float; -} - -AI_FORCE_INLINE -aiPropertyTypeInfo ai_real_to_property_type_info(double) { - return aiPTI_Double; -} -// --------------------------------------------------------------------------- - -//! @cond never - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::GetTexture( aiTextureType type, - unsigned int index, - C_STRUCT aiString* path, - aiTextureMapping* mapping /*= NULL*/, - unsigned int* uvindex /*= NULL*/, - ai_real* blend /*= NULL*/, - aiTextureOp* op /*= NULL*/, - aiTextureMapMode* mapmode /*= NULL*/) const { - return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -unsigned int aiMaterial::GetTextureCount(aiTextureType type) const { - return ::aiGetMaterialTextureCount(this,type); -} - -// --------------------------------------------------------------------------- -template <typename Type> -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx, Type* pOut, - unsigned int* pMax) const { - unsigned int iNum = pMax ? *pMax : 1; - - const aiMaterialProperty* prop; - const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx, - (const aiMaterialProperty**)&prop); - if ( AI_SUCCESS == ret ) { - - if (prop->mDataLength < sizeof(Type)*iNum) { - return AI_FAILURE; - } - - if (prop->mType != aiPTI_Buffer) { - return AI_FAILURE; - } - - iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type)); - ::memcpy(pOut,prop->mData,iNum * sizeof(Type)); - if (pMax) { - *pMax = iNum; - } - } - return ret; -} - -// --------------------------------------------------------------------------- -template <typename Type> -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,Type& pOut) const { - const aiMaterialProperty* prop; - const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx, - (const aiMaterialProperty**)&prop); - if ( AI_SUCCESS == ret ) { - - if (prop->mDataLength < sizeof(Type)) { - return AI_FAILURE; - } - - if (prop->mType != aiPTI_Buffer) { - return AI_FAILURE; - } - - ::memcpy( &pOut, prop->mData, sizeof( Type ) ); - } - return ret; -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,ai_real* pOut, - unsigned int* pMax) const { - return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax); -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,int* pOut, - unsigned int* pMax) const { - return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax); -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,ai_real& pOut) const { - return aiGetMaterialFloat(this,pKey,type,idx,&pOut); -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,int& pOut) const { - return aiGetMaterialInteger(this,pKey,type,idx,&pOut); -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiColor4D& pOut) const { - return aiGetMaterialColor(this,pKey,type,idx,&pOut); -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiColor3D& pOut) const { - aiColor4D c; - const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c); - pOut = aiColor3D(c.r,c.g,c.b); - return ret; -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiString& pOut) const { - return aiGetMaterialString(this,pKey,type,idx,&pOut); -} -// --------------------------------------------------------------------------- -AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiUVTransform& pOut) const { - return aiGetMaterialUVTransform(this,pKey,type,idx,&pOut); -} - -// --------------------------------------------------------------------------- -template<class TYPE> -aiReturn aiMaterial::AddProperty (const TYPE* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(TYPE), - pKey,type,index,aiPTI_Buffer); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE aiReturn aiMaterial::AddProperty(const float* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(float), - pKey,type,index,aiPTI_Float); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty(const double* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(double), - pKey,type,index,aiPTI_Double); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiUVTransform), - pKey,type,index,ai_real_to_property_type_info(pInput->mRotation)); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty(const aiColor4D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiColor4D), - pKey,type,index,ai_real_to_property_type_info(pInput->a)); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty(const aiColor3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiColor3D), - pKey,type,index,ai_real_to_property_type_info(pInput->b)); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty(const aiVector3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiVector3D), - pKey,type,index,ai_real_to_property_type_info(pInput->x)); -} - -// --------------------------------------------------------------------------- -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty(const int* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(int), - pKey,type,index,aiPTI_Integer); -} - - -// --------------------------------------------------------------------------- -// The template specializations below are for backwards compatibility. -// The recommended way to add material properties is using the non-template -// overloads. -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<float>(const float* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(float), - pKey,type,index,aiPTI_Float); -} - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<double>(const double* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(double), - pKey,type,index,aiPTI_Double); -} - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiUVTransform), - pKey,type,index,aiPTI_Float); -} - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiColor4D), - pKey,type,index,aiPTI_Float); -} - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiColor3D), - pKey,type,index,aiPTI_Float); -} - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(aiVector3D), - pKey,type,index,aiPTI_Float); -} - -// --------------------------------------------------------------------------- -template<> -AI_FORCE_INLINE -aiReturn aiMaterial::AddProperty<int>(const int* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) { - return AddBinaryProperty((const void*)pInput, - pNumValues * sizeof(int), - pKey,type,index,aiPTI_Integer); -} - -//! @endcond - -#endif //! AI_MATERIAL_INL_INC diff --git a/thirdparty/assimp/include/assimp/matrix3x3.h b/thirdparty/assimp/include/assimp/matrix3x3.h deleted file mode 100644 index 2c26cf92bb..0000000000 --- a/thirdparty/assimp/include/assimp/matrix3x3.h +++ /dev/null @@ -1,180 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file matrix3x3.h - * @brief Definition of a 3x3 matrix, including operators when compiling in C++ - */ -#pragma once -#ifndef AI_MATRIX3X3_H_INC -#define AI_MATRIX3X3_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/defs.h> - -#ifdef __cplusplus - -template <typename T> class aiMatrix4x4t; -template <typename T> class aiVector2t; - -// --------------------------------------------------------------------------- -/** @brief Represents a row-major 3x3 matrix - * - * There's much confusion about matrix layouts (column vs. row order). - * This is *always* a row-major matrix. Not even with the - * #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect - * matrix order - it just affects the handedness of the coordinate system - * defined thereby. - */ -template <typename TReal> -class aiMatrix3x3t { -public: - aiMatrix3x3t() AI_NO_EXCEPT : - a1(static_cast<TReal>(1.0f)), a2(), a3(), - b1(), b2(static_cast<TReal>(1.0f)), b3(), - c1(), c2(), c3(static_cast<TReal>(1.0f)) {} - - aiMatrix3x3t ( TReal _a1, TReal _a2, TReal _a3, - TReal _b1, TReal _b2, TReal _b3, - TReal _c1, TReal _c2, TReal _c3) : - a1(_a1), a2(_a2), a3(_a3), - b1(_b1), b2(_b2), b3(_b3), - c1(_c1), c2(_c2), c3(_c3) - {} - - // matrix multiplication. - aiMatrix3x3t& operator *= (const aiMatrix3x3t& m); - aiMatrix3x3t operator * (const aiMatrix3x3t& m) const; - - // array access operators - TReal* operator[] (unsigned int p_iIndex); - const TReal* operator[] (unsigned int p_iIndex) const; - - // comparison operators - bool operator== (const aiMatrix4x4t<TReal>& m) const; - bool operator!= (const aiMatrix4x4t<TReal>& m) const; - - bool Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon = 1e-6) const; - - template <typename TOther> - operator aiMatrix3x3t<TOther> () const; - - // ------------------------------------------------------------------- - /** @brief Construction from a 4x4 matrix. The remaining parts - * of the matrix are ignored. - */ - explicit aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix); - - // ------------------------------------------------------------------- - /** @brief Transpose the matrix - */ - aiMatrix3x3t& Transpose(); - - // ------------------------------------------------------------------- - /** @brief Invert the matrix. - * If the matrix is not invertible all elements are set to qnan. - * Beware, use (f != f) to check whether a TReal f is qnan. - */ - aiMatrix3x3t& Inverse(); - TReal Determinant() const; - - // ------------------------------------------------------------------- - /** @brief Returns a rotation matrix for a rotation around z - * @param a Rotation angle, in radians - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix3x3t& RotationZ(TReal a, aiMatrix3x3t& out); - - // ------------------------------------------------------------------- - /** @brief Returns a rotation matrix for a rotation around - * an arbitrary axis. - * - * @param a Rotation angle, in radians - * @param axis Axis to rotate around - * @param out To be filled - */ - static aiMatrix3x3t& Rotation( TReal a, - const aiVector3t<TReal>& axis, aiMatrix3x3t& out); - - // ------------------------------------------------------------------- - /** @brief Returns a translation matrix - * @param v Translation vector - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix3x3t& Translation( const aiVector2t<TReal>& v, aiMatrix3x3t& out); - - // ------------------------------------------------------------------- - /** @brief A function for creating a rotation matrix that rotates a - * vector called "from" into another vector called "to". - * Input : from[3], to[3] which both must be *normalized* non-zero vectors - * Output: mtx[3][3] -- a 3x3 matrix in column-major form - * Authors: Tomas Möller, John Hughes - * "Efficiently Building a Matrix to Rotate One Vector to Another" - * Journal of Graphics Tools, 4(4):1-4, 1999 - */ - static aiMatrix3x3t& FromToMatrix(const aiVector3t<TReal>& from, - const aiVector3t<TReal>& to, aiMatrix3x3t& out); - -public: - TReal a1, a2, a3; - TReal b1, b2, b3; - TReal c1, c2, c3; -}; - -typedef aiMatrix3x3t<ai_real> aiMatrix3x3; - -#else - -struct aiMatrix3x3 { - ai_real a1, a2, a3; - ai_real b1, b2, b3; - ai_real c1, c2, c3; -}; - -#endif // __cplusplus - -#endif // AI_MATRIX3X3_H_INC diff --git a/thirdparty/assimp/include/assimp/matrix3x3.inl b/thirdparty/assimp/include/assimp/matrix3x3.inl deleted file mode 100644 index 1ce8c9691c..0000000000 --- a/thirdparty/assimp/include/assimp/matrix3x3.inl +++ /dev/null @@ -1,361 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file matrix3x3.inl - * @brief Inline implementation of the 3x3 matrix operators - */ -#pragma once -#ifndef AI_MATRIX3X3_INL_INC -#define AI_MATRIX3X3_INL_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -#include <assimp/matrix3x3.h> -#include <assimp/matrix4x4.h> - -#include <algorithm> -#include <cmath> -#include <limits> - -// ------------------------------------------------------------------------------------------------ -// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored. -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix) { - a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3; - b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3; - c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m) { - *this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3, - m.a2 * a1 + m.b2 * a2 + m.c2 * a3, - m.a3 * a1 + m.b3 * a2 + m.c3 * a3, - m.a1 * b1 + m.b1 * b2 + m.c1 * b3, - m.a2 * b1 + m.b2 * b2 + m.c2 * b3, - m.a3 * b1 + m.b3 * b2 + m.c3 * b3, - m.a1 * c1 + m.b1 * c2 + m.c1 * c3, - m.a2 * c1 + m.b2 * c2 + m.c2 * c3, - m.a3 * c1 + m.b3 * c2 + m.c3 * c3); - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -template <typename TOther> -aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const { - return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3), - static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3), - static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3)); -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const { - aiMatrix3x3t<TReal> temp( *this); - temp *= m; - return temp; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) { - switch ( p_iIndex ) { - case 0: - return &a1; - case 1: - return &b1; - case 2: - return &c1; - default: - break; - } - return &a1; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const { - switch ( p_iIndex ) { - case 0: - return &a1; - case 1: - return &b1; - case 2: - return &c1; - default: - break; - } - return &a1; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const { - return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && - b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && - c1 == m.c1 && c2 == m.c2 && c3 == m.c3; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const { - return !(*this == m); -} - -// --------------------------------------------------------------------------- -template<typename TReal> -AI_FORCE_INLINE -bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { - return - std::abs(a1 - m.a1) <= epsilon && - std::abs(a2 - m.a2) <= epsilon && - std::abs(a3 - m.a3) <= epsilon && - std::abs(b1 - m.b1) <= epsilon && - std::abs(b2 - m.b2) <= epsilon && - std::abs(b3 - m.b3) <= epsilon && - std::abs(c1 - m.c1) <= epsilon && - std::abs(c2 - m.c2) <= epsilon && - std::abs(c3 - m.c3) <= epsilon; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() { - // (TReal&) don't remove, GCC complains cause of packed fields - std::swap( (TReal&)a2, (TReal&)b1); - std::swap( (TReal&)a3, (TReal&)c1); - std::swap( (TReal&)b3, (TReal&)c2); - return *this; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -TReal aiMatrix3x3t<TReal>::Determinant() const { - return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() { - // Compute the reciprocal determinant - TReal det = Determinant(); - if(det == static_cast<TReal>(0.0)) - { - // Matrix not invertible. Setting all elements to nan is not really - // correct in a mathematical sense; but at least qnans are easy to - // spot. XXX we might throw an exception instead, which would - // be even much better to spot :/. - const TReal nan = std::numeric_limits<TReal>::quiet_NaN(); - *this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan); - - return *this; - } - - TReal invdet = static_cast<TReal>(1.0) / det; - - aiMatrix3x3t<TReal> res; - res.a1 = invdet * (b2 * c3 - b3 * c2); - res.a2 = -invdet * (a2 * c3 - a3 * c2); - res.a3 = invdet * (a2 * b3 - a3 * b2); - res.b1 = -invdet * (b1 * c3 - b3 * c1); - res.b2 = invdet * (a1 * c3 - a3 * c1); - res.b3 = -invdet * (a1 * b3 - a3 * b1); - res.c1 = invdet * (b1 * c2 - b2 * c1); - res.c2 = -invdet * (a1 * c2 - a2 * c1); - res.c3 = invdet * (a1 * b2 - a2 * b1); - *this = res; - - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out) { - out.a1 = out.b2 = std::cos(a); - out.b1 = std::sin(a); - out.a2 = - out.b1; - - out.a3 = out.b3 = out.c1 = out.c2 = 0.f; - out.c3 = 1.f; - - return out; -} - -// ------------------------------------------------------------------------------------------------ -// Returns a rotation matrix for a rotation around an arbitrary axis. -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out) { - TReal c = std::cos( a), s = std::sin( a), t = 1 - c; - TReal x = axis.x, y = axis.y, z = axis.z; - - // Many thanks to MathWorld and Wikipedia - out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y; - out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x; - out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c; - - return out; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out) { - out = aiMatrix3x3t<TReal>(); - out.a3 = v.x; - out.b3 = v.y; - return out; -} - -// ---------------------------------------------------------------------------------------- -/** A function for creating a rotation matrix that rotates a vector called - * "from" into another vector called "to". - * Input : from[3], to[3] which both must be *normalized* non-zero vectors - * Output: mtx[3][3] -- a 3x3 matrix in colum-major form - * Authors: Tomas Möller, John Hughes - * "Efficiently Building a Matrix to Rotate One Vector to Another" - * Journal of Graphics Tools, 4(4):1-4, 1999 - */ -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, - const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx) { - const TReal e = from * to; - const TReal f = (e < 0)? -e:e; - - if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001)) /* "from" and "to"-vector almost parallel */ - { - aiVector3D u,v; /* temporary storage vectors */ - aiVector3D x; /* vector most nearly orthogonal to "from" */ - - x.x = (from.x > 0.0)? from.x : -from.x; - x.y = (from.y > 0.0)? from.y : -from.y; - x.z = (from.z > 0.0)? from.z : -from.z; - - if (x.x < x.y) - { - if (x.x < x.z) - { - x.x = static_cast<TReal>(1.0); - x.y = x.z = static_cast<TReal>(0.0); - } - else - { - x.z = static_cast<TReal>(1.0); - x.x = x.y = static_cast<TReal>(0.0); - } - } - else - { - if (x.y < x.z) - { - x.y = static_cast<TReal>(1.0); - x.x = x.z = static_cast<TReal>(0.0); - } - else - { - x.z = static_cast<TReal>(1.0); - x.x = x.y = static_cast<TReal>(0.0); - } - } - - u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z; - v.x = x.x - to.x; v.y = x.y - to.y; v.z = x.z - to.z; - - const TReal c1_ = static_cast<TReal>(2.0) / (u * u); - const TReal c2_ = static_cast<TReal>(2.0) / (v * v); - const TReal c3_ = c1_ * c2_ * (u * v); - - for (unsigned int i = 0; i < 3; i++) - { - for (unsigned int j = 0; j < 3; j++) - { - mtx[i][j] = - c1_ * u[i] * u[j] - c2_ * v[i] * v[j] - + c3_ * v[i] * u[j]; - } - mtx[i][i] += static_cast<TReal>(1.0); - } - } - else /* the most common case, unless "from"="to", or "from"=-"to" */ - { - const aiVector3D v = from ^ to; - /* ... use this hand optimized version (9 mults less) */ - const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e); /* optimization by Gottfried Chen */ - const TReal hvx = h * v.x; - const TReal hvz = h * v.z; - const TReal hvxy = hvx * v.y; - const TReal hvxz = hvx * v.z; - const TReal hvyz = hvz * v.y; - mtx[0][0] = e + hvx * v.x; - mtx[0][1] = hvxy - v.z; - mtx[0][2] = hvxz + v.y; - - mtx[1][0] = hvxy + v.z; - mtx[1][1] = e + h * v.y * v.y; - mtx[1][2] = hvyz - v.x; - - mtx[2][0] = hvxz - v.y; - mtx[2][1] = hvyz + v.x; - mtx[2][2] = e + hvz * v.z; - } - return mtx; -} - -#endif // __cplusplus -#endif // AI_MATRIX3X3_INL_INC diff --git a/thirdparty/assimp/include/assimp/matrix4x4.h b/thirdparty/assimp/include/assimp/matrix4x4.h deleted file mode 100644 index 8fc216f669..0000000000 --- a/thirdparty/assimp/include/assimp/matrix4x4.h +++ /dev/null @@ -1,276 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file matrix4x4.h - * @brief 4x4 matrix structure, including operators when compiling in C++ - */ -#pragma once -#ifndef AI_MATRIX4X4_H_INC -#define AI_MATRIX4X4_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/vector3.h> -#include <assimp/defs.h> - -#ifdef __cplusplus - -template<typename TReal> class aiMatrix3x3t; -template<typename TReal> class aiQuaterniont; - -// --------------------------------------------------------------------------- -/** @brief Represents a row-major 4x4 matrix, use this for homogeneous - * coordinates. - * - * There's much confusion about matrix layouts (column vs. row order). - * This is *always* a row-major matrix. Not even with the - * #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect - * matrix order - it just affects the handedness of the coordinate system - * defined thereby. - */ -template<typename TReal> -class aiMatrix4x4t { -public: - - /** set to identity */ - aiMatrix4x4t() AI_NO_EXCEPT; - - /** construction from single values */ - aiMatrix4x4t ( TReal _a1, TReal _a2, TReal _a3, TReal _a4, - TReal _b1, TReal _b2, TReal _b3, TReal _b4, - TReal _c1, TReal _c2, TReal _c3, TReal _c4, - TReal _d1, TReal _d2, TReal _d3, TReal _d4); - - - /** construction from 3x3 matrix, remaining elements are set to identity */ - explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m); - - /** construction from position, rotation and scaling components - * @param scaling The scaling for the x,y,z axes - * @param rotation The rotation as a hamilton quaternion - * @param position The position for the x,y,z axes - */ - aiMatrix4x4t(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, - const aiVector3t<TReal>& position); - - // array access operators - /** @fn TReal* operator[] (unsigned int p_iIndex) - * @param [in] p_iIndex - index of the row. - * @return pointer to pointed row. - */ - TReal* operator[] (unsigned int p_iIndex); - - /** @fn const TReal* operator[] (unsigned int p_iIndex) const - * @overload TReal* operator[] (unsigned int p_iIndex) - */ - const TReal* operator[] (unsigned int p_iIndex) const; - - // comparison operators - bool operator== (const aiMatrix4x4t& m) const; - bool operator!= (const aiMatrix4x4t& m) const; - - bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const; - - // matrix multiplication. - aiMatrix4x4t& operator *= (const aiMatrix4x4t& m); - aiMatrix4x4t operator * (const aiMatrix4x4t& m) const; - aiMatrix4x4t operator * (const TReal& aFloat) const; - aiMatrix4x4t operator + (const aiMatrix4x4t& aMatrix) const; - - template <typename TOther> - operator aiMatrix4x4t<TOther> () const; - - // ------------------------------------------------------------------- - /** @brief Transpose the matrix */ - aiMatrix4x4t& Transpose(); - - // ------------------------------------------------------------------- - /** @brief Invert the matrix. - * If the matrix is not invertible all elements are set to qnan. - * Beware, use (f != f) to check whether a TReal f is qnan. - */ - aiMatrix4x4t& Inverse(); - TReal Determinant() const; - - - // ------------------------------------------------------------------- - /** @brief Returns true of the matrix is the identity matrix. - * The check is performed against a not so small epsilon. - */ - inline bool IsIdentity() const; - - // ------------------------------------------------------------------- - /** @brief Decompose a trafo matrix into its original components - * @param scaling Receives the output scaling for the x,y,z axes - * @param rotation Receives the output rotation as a hamilton - * quaternion - * @param position Receives the output position for the x,y,z axes - */ - void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, - aiVector3t<TReal>& position) const; - - // ------------------------------------------------------------------- - /** @fn void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const - * @brief Decompose a trafo matrix into its original components. - * Thx to good FAQ at http://www.gamedev.ru/code/articles/faq_matrix_quat - * @param [out] pScaling - Receives the output scaling for the x,y,z axes. - * @param [out] pRotation - Receives the output rotation as a Euler angles. - * @param [out] pPosition - Receives the output position for the x,y,z axes. - */ - void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const; - - // ------------------------------------------------------------------- - /** @fn void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, aiVector3t<TReal>& pPosition) const - * @brief Decompose a trafo matrix into its original components - * Thx to good FAQ at http://www.gamedev.ru/code/articles/faq_matrix_quat - * @param [out] pScaling - Receives the output scaling for the x,y,z axes. - * @param [out] pRotationAxis - Receives the output rotation axis. - * @param [out] pRotationAngle - Receives the output rotation angle for @ref pRotationAxis. - * @param [out] pPosition - Receives the output position for the x,y,z axes. - */ - void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, aiVector3t<TReal>& pPosition) const; - - // ------------------------------------------------------------------- - /** @brief Decompose a trafo matrix with no scaling into its - * original components - * @param rotation Receives the output rotation as a hamilton - * quaternion - * @param position Receives the output position for the x,y,z axes - */ - void DecomposeNoScaling (aiQuaterniont<TReal>& rotation, - aiVector3t<TReal>& position) const; - - // ------------------------------------------------------------------- - /** @brief Creates a trafo matrix from a set of euler angles - * @param x Rotation angle for the x-axis, in radians - * @param y Rotation angle for the y-axis, in radians - * @param z Rotation angle for the z-axis, in radians - */ - aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z); - aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb); - - // ------------------------------------------------------------------- - /** @brief Returns a rotation matrix for a rotation around the x axis - * @param a Rotation angle, in radians - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix4x4t& RotationX(TReal a, aiMatrix4x4t& out); - - // ------------------------------------------------------------------- - /** @brief Returns a rotation matrix for a rotation around the y axis - * @param a Rotation angle, in radians - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix4x4t& RotationY(TReal a, aiMatrix4x4t& out); - - // ------------------------------------------------------------------- - /** @brief Returns a rotation matrix for a rotation around the z axis - * @param a Rotation angle, in radians - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix4x4t& RotationZ(TReal a, aiMatrix4x4t& out); - - // ------------------------------------------------------------------- - /** Returns a rotation matrix for a rotation around an arbitrary axis. - * @param a Rotation angle, in radians - * @param axis Rotation axis, should be a normalized vector. - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis, - aiMatrix4x4t& out); - - // ------------------------------------------------------------------- - /** @brief Returns a translation matrix - * @param v Translation vector - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v, - aiMatrix4x4t& out); - - // ------------------------------------------------------------------- - /** @brief Returns a scaling matrix - * @param v Scaling vector - * @param out Receives the output matrix - * @return Reference to the output matrix - */ - static aiMatrix4x4t& Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t& out); - - // ------------------------------------------------------------------- - /** @brief A function for creating a rotation matrix that rotates a - * vector called "from" into another vector called "to". - * Input : from[3], to[3] which both must be *normalized* non-zero vectors - * Output: mtx[3][3] -- a 3x3 matrix in column-major form - * Authors: Tomas Mueller, John Hughes - * "Efficiently Building a Matrix to Rotate One Vector to Another" - * Journal of Graphics Tools, 4(4):1-4, 1999 - */ - static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from, - const aiVector3t<TReal>& to, aiMatrix4x4t& out); - - TReal a1, a2, a3, a4; - TReal b1, b2, b3, b4; - TReal c1, c2, c3, c4; - TReal d1, d2, d3, d4; -}; - -typedef aiMatrix4x4t<ai_real> aiMatrix4x4; - -#else - -struct aiMatrix4x4 { - ai_real a1, a2, a3, a4; - ai_real b1, b2, b3, b4; - ai_real c1, c2, c3, c4; - ai_real d1, d2, d3, d4; -}; - - -#endif // __cplusplus - -#endif // AI_MATRIX4X4_H_INC diff --git a/thirdparty/assimp/include/assimp/matrix4x4.inl b/thirdparty/assimp/include/assimp/matrix4x4.inl deleted file mode 100644 index 84079974f7..0000000000 --- a/thirdparty/assimp/include/assimp/matrix4x4.inl +++ /dev/null @@ -1,677 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file matrix4x4.inl - * @brief Inline implementation of the 4x4 matrix operators - */ -#pragma once -#ifndef AI_MATRIX4X4_INL_INC -#define AI_MATRIX4X4_INL_INC - -#ifdef __cplusplus - -#include "matrix4x4.h" -#include "matrix3x3.h" -#include "quaternion.h" -#include "MathFunctions.h" - -#include <algorithm> -#include <limits> -#include <cmath> - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -aiMatrix4x4t<TReal>::aiMatrix4x4t() AI_NO_EXCEPT : - a1(1.0f), a2(), a3(), a4(), - b1(), b2(1.0f), b3(), b4(), - c1(), c2(), c3(1.0f), c4(), - d1(), d2(), d3(), d4(1.0f) { - // empty -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -aiMatrix4x4t<TReal>::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4, - TReal _b1, TReal _b2, TReal _b3, TReal _b4, - TReal _c1, TReal _c2, TReal _c3, TReal _c4, - TReal _d1, TReal _d2, TReal _d3, TReal _d4) : - a1(_a1), a2(_a2), a3(_a3), a4(_a4), - b1(_b1), b2(_b2), b3(_b3), b4(_b4), - c1(_c1), c2(_c2), c3(_c3), c4(_c4), - d1(_d1), d2(_d2), d3(_d3), d4(_d4) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -template <typename TOther> -aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const { - return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4), - static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4), - static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4), - static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4)); -} - - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) { - a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0); - b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0); - c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0); - d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0); -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position) { - // build a 3x3 rotation matrix - aiMatrix3x3t<TReal> m = rotation.GetMatrix(); - - a1 = m.a1 * scaling.x; - a2 = m.a2 * scaling.x; - a3 = m.a3 * scaling.x; - a4 = position.x; - - b1 = m.b1 * scaling.y; - b2 = m.b2 * scaling.y; - b3 = m.b3 * scaling.y; - b4 = position.y; - - c1 = m.c1 * scaling.z; - c2 = m.c2 * scaling.z; - c3 = m.c3 * scaling.z; - c4= position.z; - - d1 = static_cast<TReal>(0.0); - d2 = static_cast<TReal>(0.0); - d3 = static_cast<TReal>(0.0); - d4 = static_cast<TReal>(1.0); -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) { - *this = aiMatrix4x4t<TReal>( - m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4, - m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4, - m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4, - m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4, - m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4, - m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4, - m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4, - m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4, - m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4, - m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4, - m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4, - m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4, - m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4, - m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4, - m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4, - m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4); - return *this; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const { - aiMatrix4x4t<TReal> temp( - a1 * aFloat, - a2 * aFloat, - a3 * aFloat, - a4 * aFloat, - b1 * aFloat, - b2 * aFloat, - b3 * aFloat, - b4 * aFloat, - c1 * aFloat, - c2 * aFloat, - c3 * aFloat, - c4 * aFloat, - d1 * aFloat, - d2 * aFloat, - d3 * aFloat, - d4 * aFloat); - return temp; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const { - aiMatrix4x4t<TReal> temp( - m.a1 + a1, - m.a2 + a2, - m.a3 + a3, - m.a4 + a4, - m.b1 + b1, - m.b2 + b2, - m.b3 + b3, - m.b4 + b4, - m.c1 + c1, - m.c2 + c2, - m.c3 + c3, - m.c4 + c4, - m.d1 + d1, - m.d2 + d2, - m.d3 + d3, - m.d4 + d4); - return temp; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const { - aiMatrix4x4t<TReal> temp( *this); - temp *= m; - return temp; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() { - // (TReal&) don't remove, GCC complains cause of packed fields - std::swap( (TReal&)b1, (TReal&)a2); - std::swap( (TReal&)c1, (TReal&)a3); - std::swap( (TReal&)c2, (TReal&)b3); - std::swap( (TReal&)d1, (TReal&)a4); - std::swap( (TReal&)d2, (TReal&)b4); - std::swap( (TReal&)d3, (TReal&)c4); - return *this; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -TReal aiMatrix4x4t<TReal>::Determinant() const { - return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4 - + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4 - - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3 - + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2 - + a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2 - - a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() { - // Compute the reciprocal determinant - const TReal det = Determinant(); - if(det == static_cast<TReal>(0.0)) - { - // Matrix not invertible. Setting all elements to nan is not really - // correct in a mathematical sense but it is easy to debug for the - // programmer. - const TReal nan = std::numeric_limits<TReal>::quiet_NaN(); - *this = aiMatrix4x4t<TReal>( - nan,nan,nan,nan, - nan,nan,nan,nan, - nan,nan,nan,nan, - nan,nan,nan,nan); - - return *this; - } - - const TReal invdet = static_cast<TReal>(1.0) / det; - - aiMatrix4x4t<TReal> res; - res.a1 = invdet * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2)); - res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2)); - res.a3 = invdet * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2)); - res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2)); - res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1)); - res.b2 = invdet * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1)); - res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1)); - res.b4 = invdet * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1)); - res.c1 = invdet * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1)); - res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1)); - res.c3 = invdet * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1)); - res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1)); - res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1)); - res.d2 = invdet * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1)); - res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1)); - res.d4 = invdet * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1)); - *this = res; - - return *this; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) { - if (p_iIndex > 3) { - return nullptr; - } - switch ( p_iIndex ) { - case 0: - return &a1; - case 1: - return &b1; - case 2: - return &c1; - case 3: - return &d1; - default: - break; - } - return &a1; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const { - if (p_iIndex > 3) { - return nullptr; - } - - switch ( p_iIndex ) { - case 0: - return &a1; - case 1: - return &b1; - case 2: - return &c1; - case 3: - return &d1; - default: - break; - } - return &a1; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const { - return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 && - b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 && - c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 && - d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4); -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const { - return !(*this == m); -} - -// --------------------------------------------------------------------------- -template<typename TReal> -AI_FORCE_INLINE -bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { - return - std::abs(a1 - m.a1) <= epsilon && - std::abs(a2 - m.a2) <= epsilon && - std::abs(a3 - m.a3) <= epsilon && - std::abs(a4 - m.a4) <= epsilon && - std::abs(b1 - m.b1) <= epsilon && - std::abs(b2 - m.b2) <= epsilon && - std::abs(b3 - m.b3) <= epsilon && - std::abs(b4 - m.b4) <= epsilon && - std::abs(c1 - m.c1) <= epsilon && - std::abs(c2 - m.c2) <= epsilon && - std::abs(c3 - m.c3) <= epsilon && - std::abs(c4 - m.c4) <= epsilon && - std::abs(d1 - m.d1) <= epsilon && - std::abs(d2 - m.d2) <= epsilon && - std::abs(d3 - m.d3) <= epsilon && - std::abs(d4 - m.d4) <= epsilon; -} - -// ---------------------------------------------------------------------------------------- - -#define ASSIMP_MATRIX4_4_DECOMPOSE_PART \ - const aiMatrix4x4t<TReal>& _this = *this;/* Create alias for conveniance. */ \ - \ - /* extract translation */ \ - pPosition.x = _this[0][3]; \ - pPosition.y = _this[1][3]; \ - pPosition.z = _this[2][3]; \ - \ - /* extract the columns of the matrix. */ \ - aiVector3t<TReal> vCols[3] = { \ - aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), \ - aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), \ - aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) \ - }; \ - \ - /* extract the scaling factors */ \ - pScaling.x = vCols[0].Length(); \ - pScaling.y = vCols[1].Length(); \ - pScaling.z = vCols[2].Length(); \ - \ - /* and the sign of the scaling */ \ - if (Determinant() < 0) pScaling = -pScaling; \ - \ - /* and remove all scaling from the matrix */ \ - if(pScaling.x) vCols[0] /= pScaling.x; \ - if(pScaling.y) vCols[1] /= pScaling.y; \ - if(pScaling.z) vCols[2] /= pScaling.z; \ - \ - do {} while(false) - -template <typename TReal> -AI_FORCE_INLINE -void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation, - aiVector3t<TReal>& pPosition) const { - ASSIMP_MATRIX4_4_DECOMPOSE_PART; - - // build a 3x3 rotation matrix - aiMatrix3x3t<TReal> m(vCols[0].x,vCols[1].x,vCols[2].x, - vCols[0].y,vCols[1].y,vCols[2].y, - vCols[0].z,vCols[1].z,vCols[2].z); - - // and generate the rotation quaternion from it - pRotation = aiQuaterniont<TReal>(m); -} - -template <typename TReal> -AI_FORCE_INLINE -void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const { - ASSIMP_MATRIX4_4_DECOMPOSE_PART; - - /* - assuming a right-handed coordinate system - and post-multiplication of column vectors, - the rotation matrix for an euler XYZ rotation is M = Rz * Ry * Rx. - combining gives: - - | CE BDE-AF ADE+BF 0 | - M = | CF BDF+AE ADF-BE 0 | - | -D CB AC 0 | - | 0 0 0 1 | - - where - A = cos(angle_x), B = sin(angle_x); - C = cos(angle_y), D = sin(angle_y); - E = cos(angle_z), F = sin(angle_z); - */ - - // Use a small epsilon to solve floating-point inaccuracies - const TReal epsilon = Assimp::Math::getEpsilon<TReal>(); - - pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY. - - TReal C = std::cos(pRotation.y); - - if(std::fabs(C) > epsilon) - { - // Finding angle around oX. - TReal tan_x = vCols[2].z / C;// A - TReal tan_y = vCols[1].z / C;// B - - pRotation.x = std::atan2(tan_y, tan_x); - // Finding angle around oZ. - tan_x = vCols[0].x / C;// E - tan_y = vCols[0].y / C;// F - pRotation.z = std::atan2(tan_y, tan_x); - } - else - {// oY is fixed. - pRotation.x = 0;// Set angle around oX to 0. => A == 1, B == 0, C == 0, D == 1. - - // And finding angle around oZ. - TReal tan_x = vCols[1].y;// BDF+AE => E - TReal tan_y = -vCols[1].x;// BDE-AF => F - - pRotation.z = std::atan2(tan_y, tan_x); - } -} - -#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART - -template <typename TReal> -AI_FORCE_INLINE -void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, - aiVector3t<TReal>& pPosition) const { - aiQuaterniont<TReal> pRotation; - - Decompose(pScaling, pRotation, pPosition); - pRotation.Normalize(); - - TReal angle_cos = pRotation.w; - TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos); - - pRotationAngle = std::acos(angle_cos) * 2; - - // Use a small epsilon to solve floating-point inaccuracies - const TReal epsilon = 10e-3f; - - if(std::fabs(angle_sin) < epsilon) angle_sin = 1; - - pRotationAxis.x = pRotation.x / angle_sin; - pRotationAxis.y = pRotation.y / angle_sin; - pRotationAxis.z = pRotation.z / angle_sin; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation, - aiVector3t<TReal>& position) const { - const aiMatrix4x4t<TReal>& _this = *this; - - // extract translation - position.x = _this[0][3]; - position.y = _this[1][3]; - position.z = _this[2][3]; - - // extract rotation - rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this); -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) { - return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z); -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) { - aiMatrix4x4t<TReal>& _this = *this; - - TReal cx = std::cos(x); - TReal sx = std::sin(x); - TReal cy = std::cos(y); - TReal sy = std::sin(y); - TReal cz = std::cos(z); - TReal sz = std::sin(z); - - // mz*my*mx - _this.a1 = cz * cy; - _this.a2 = cz * sy * sx - sz * cx; - _this.a3 = sz * sx + cz * sy * cx; - - _this.b1 = sz * cy; - _this.b2 = cz * cx + sz * sy * sx; - _this.b3 = sz * sy * cx - cz * sx; - - _this.c1 = -sy; - _this.c2 = cy * sx; - _this.c3 = cy * cx; - - return *this; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -bool aiMatrix4x4t<TReal>::IsIdentity() const { - // Use a small epsilon to solve floating-point inaccuracies - const static TReal epsilon = 10e-3f; - - return (a2 <= epsilon && a2 >= -epsilon && - a3 <= epsilon && a3 >= -epsilon && - a4 <= epsilon && a4 >= -epsilon && - b1 <= epsilon && b1 >= -epsilon && - b3 <= epsilon && b3 >= -epsilon && - b4 <= epsilon && b4 >= -epsilon && - c1 <= epsilon && c1 >= -epsilon && - c2 <= epsilon && c2 >= -epsilon && - c4 <= epsilon && c4 >= -epsilon && - d1 <= epsilon && d1 >= -epsilon && - d2 <= epsilon && d2 >= -epsilon && - d3 <= epsilon && d3 >= -epsilon && - a1 <= 1.f+epsilon && a1 >= 1.f-epsilon && - b2 <= 1.f+epsilon && b2 >= 1.f-epsilon && - c3 <= 1.f+epsilon && c3 >= 1.f-epsilon && - d4 <= 1.f+epsilon && d4 >= 1.f-epsilon); -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) { - /* - | 1 0 0 0 | - M = | 0 cos(A) -sin(A) 0 | - | 0 sin(A) cos(A) 0 | - | 0 0 0 1 | */ - out = aiMatrix4x4t<TReal>(); - out.b2 = out.c3 = std::cos(a); - out.b3 = -(out.c2 = std::sin(a)); - return out; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) { - /* - | cos(A) 0 sin(A) 0 | - M = | 0 1 0 0 | - | -sin(A) 0 cos(A) 0 | - | 0 0 0 1 | - */ - out = aiMatrix4x4t<TReal>(); - out.a1 = out.c3 = std::cos(a); - out.c1 = -(out.a3 = std::sin(a)); - return out; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) { - /* - | cos(A) -sin(A) 0 0 | - M = | sin(A) cos(A) 0 0 | - | 0 0 1 0 | - | 0 0 0 1 | */ - out = aiMatrix4x4t<TReal>(); - out.a1 = out.b2 = std::cos(a); - out.a2 = -(out.b1 = std::sin(a)); - return out; -} - -// ---------------------------------------------------------------------------------------- -// Returns a rotation matrix for a rotation around an arbitrary axis. -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out) { - TReal c = std::cos( a), s = std::sin( a), t = 1 - c; - TReal x = axis.x, y = axis.y, z = axis.z; - - // Many thanks to MathWorld and Wikipedia - out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y; - out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x; - out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c; - out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0); - out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0); - out.d4 = static_cast<TReal>(1.0); - - return out; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) { - out = aiMatrix4x4t<TReal>(); - out.a4 = v.x; - out.b4 = v.y; - out.c4 = v.z; - return out; -} - -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) { - out = aiMatrix4x4t<TReal>(); - out.a1 = v.x; - out.b2 = v.y; - out.c3 = v.z; - return out; -} - -// ---------------------------------------------------------------------------------------- -/** A function for creating a rotation matrix that rotates a vector called - * "from" into another vector called "to". - * Input : from[3], to[3] which both must be *normalized* non-zero vectors - * Output: mtx[3][3] -- a 3x3 matrix in colum-major form - * Authors: Tomas Möller, John Hughes - * "Efficiently Building a Matrix to Rotate One Vector to Another" - * Journal of Graphics Tools, 4(4):1-4, 1999 - */ -// ---------------------------------------------------------------------------------------- -template <typename TReal> -AI_FORCE_INLINE -aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, - const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) { - aiMatrix3x3t<TReal> m3; - aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3); - mtx = aiMatrix4x4t<TReal>(m3); - return mtx; -} - -#endif // __cplusplus -#endif // AI_MATRIX4X4_INL_INC diff --git a/thirdparty/assimp/include/assimp/mesh.h b/thirdparty/assimp/include/assimp/mesh.h deleted file mode 100644 index fbf2a857ad..0000000000 --- a/thirdparty/assimp/include/assimp/mesh.h +++ /dev/null @@ -1,879 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file mesh.h - * @brief Declares the data structures in which the imported geometry is - returned by ASSIMP: aiMesh, aiFace and aiBone data structures. - */ -#pragma once -#ifndef AI_MESH_H_INC -#define AI_MESH_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> -#include <assimp/aabb.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------------- -// Limits. These values are required to match the settings Assimp was -// compiled against. Therefore, do not redefine them unless you build the -// library from source using the same definitions. -// --------------------------------------------------------------------------- - -/** @def AI_MAX_FACE_INDICES - * Maximum number of indices per face (polygon). */ - -#ifndef AI_MAX_FACE_INDICES -# define AI_MAX_FACE_INDICES 0x7fff -#endif - -/** @def AI_MAX_BONE_WEIGHTS - * Maximum number of indices per face (polygon). */ - -#ifndef AI_MAX_BONE_WEIGHTS -# define AI_MAX_BONE_WEIGHTS 0x7fffffff -#endif - -/** @def AI_MAX_VERTICES - * Maximum number of vertices per mesh. */ - -#ifndef AI_MAX_VERTICES -# define AI_MAX_VERTICES 0x7fffffff -#endif - -/** @def AI_MAX_FACES - * Maximum number of faces per mesh. */ - -#ifndef AI_MAX_FACES -# define AI_MAX_FACES 0x7fffffff -#endif - -/** @def AI_MAX_NUMBER_OF_COLOR_SETS - * Supported number of vertex color sets per mesh. */ - -#ifndef AI_MAX_NUMBER_OF_COLOR_SETS -# define AI_MAX_NUMBER_OF_COLOR_SETS 0x8 -#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS - -/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS - * Supported number of texture coord sets (UV(W) channels) per mesh */ - -#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS -# define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8 -#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS - -// --------------------------------------------------------------------------- -/** @brief A single face in a mesh, referring to multiple vertices. - * - * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3 - * it's called 'polygon' (hey, that's just a definition!). - * <br> - * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of - * primitive are actually present in a mesh. The #aiProcess_SortByPType flag - * executes a special post-processing algorithm which splits meshes with - * *different* primitive types mixed up (e.g. lines and triangles) in several - * 'clean' submeshes. Furthermore there is a configuration option ( - * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove - * specific kinds of primitives from the imported scene, completely and forever. - * In many cases you'll probably want to set this setting to - * @code - * aiPrimitiveType_LINE|aiPrimitiveType_POINT - * @endcode - * Together with the #aiProcess_Triangulate flag you can then be sure that - * #aiFace::mNumIndices is always 3. - * @note Take a look at the @link data Data Structures page @endlink for - * more information on the layout and winding order of a face. - */ -struct aiFace -{ - //! Number of indices defining this face. - //! The maximum value for this member is #AI_MAX_FACE_INDICES. - unsigned int mNumIndices; - - //! Pointer to the indices array. Size of the array is given in numIndices. - unsigned int* mIndices; - -#ifdef __cplusplus - - //! Default constructor - aiFace() AI_NO_EXCEPT - : mNumIndices( 0 ) - , mIndices( nullptr ) { - // empty - } - - //! Default destructor. Delete the index array - ~aiFace() - { - delete [] mIndices; - } - - //! Copy constructor. Copy the index array - aiFace( const aiFace& o) - : mNumIndices(0) - , mIndices( nullptr ) { - *this = o; - } - - //! Assignment operator. Copy the index array - aiFace& operator = ( const aiFace& o) { - if (&o == this) { - return *this; - } - - delete[] mIndices; - mNumIndices = o.mNumIndices; - if (mNumIndices) { - mIndices = new unsigned int[mNumIndices]; - ::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int)); - } else { - mIndices = nullptr; - } - - return *this; - } - - //! Comparison operator. Checks whether the index array - //! of two faces is identical - bool operator== (const aiFace& o) const { - if (mIndices == o.mIndices) { - return true; - } - - if (nullptr != mIndices && mNumIndices != o.mNumIndices) { - return false; - } - - if (nullptr == mIndices) { - return false; - } - - for (unsigned int i = 0; i < this->mNumIndices; ++i) { - if (mIndices[i] != o.mIndices[i]) { - return false; - } - } - - return true; - } - - //! Inverse comparison operator. Checks whether the index - //! array of two faces is NOT identical - bool operator != (const aiFace& o) const { - return !(*this == o); - } -#endif // __cplusplus -}; // struct aiFace - - -// --------------------------------------------------------------------------- -/** @brief A single influence of a bone on a vertex. - */ -struct aiVertexWeight { - //! Index of the vertex which is influenced by the bone. - unsigned int mVertexId; - - //! The strength of the influence in the range (0...1). - //! The influence from all bones at one vertex amounts to 1. - float mWeight; - -#ifdef __cplusplus - - //! Default constructor - aiVertexWeight() AI_NO_EXCEPT - : mVertexId(0) - , mWeight(0.0f) { - // empty - } - - //! Initialization from a given index and vertex weight factor - //! \param pID ID - //! \param pWeight Vertex weight factor - aiVertexWeight( unsigned int pID, float pWeight ) - : mVertexId( pID ) - , mWeight( pWeight ) { - // empty - } - - bool operator == ( const aiVertexWeight &rhs ) const { - return ( mVertexId == rhs.mVertexId && mWeight == rhs.mWeight ); - } - - bool operator != ( const aiVertexWeight &rhs ) const { - return ( *this == rhs ); - } - -#endif // __cplusplus -}; - - -// Forward declare aiNode (pointer use only) -struct aiNode; - -// --------------------------------------------------------------------------- -/** @brief A single bone of a mesh. - * - * A bone has a name by which it can be found in the frame hierarchy and by - * which it can be addressed by animations. In addition it has a number of - * influences on vertices, and a matrix relating the mesh position to the - * position of the bone at the time of binding. - */ -struct aiBone { - //! The name of the bone. - C_STRUCT aiString mName; - - //! The number of vertices affected by this bone. - //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS. - unsigned int mNumWeights; - -#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS - // The bone armature node - used for skeleton conversion - // you must enable aiProcess_PopulateArmatureData to populate this - C_STRUCT aiNode* mArmature; - - // The bone node in the scene - used for skeleton conversion - // you must enable aiProcess_PopulateArmatureData to populate this - C_STRUCT aiNode* mNode; - -#endif - //! The influence weights of this bone, by vertex index. - C_STRUCT aiVertexWeight* mWeights; - - /** Matrix that transforms from bone space to mesh space in bind pose. - * - * This matrix describes the position of the mesh - * in the local space of this bone when the skeleton was bound. - * Thus it can be used directly to determine a desired vertex position, - * given the world-space transform of the bone when animated, - * and the position of the vertex in mesh space. - * - * It is sometimes called an inverse-bind matrix, - * or inverse bind pose matrix. - */ - C_STRUCT aiMatrix4x4 mOffsetMatrix; - -#ifdef __cplusplus - - //! Default constructor - aiBone() AI_NO_EXCEPT - : mName() - , mNumWeights( 0 ) - , mWeights( nullptr ) - , mOffsetMatrix() { - // empty - } - - //! Copy constructor - aiBone(const aiBone& other) - : mName( other.mName ) - , mNumWeights( other.mNumWeights ) - , mWeights(nullptr) - , mOffsetMatrix( other.mOffsetMatrix ) { - if (other.mWeights && other.mNumWeights) { - mWeights = new aiVertexWeight[mNumWeights]; - ::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight)); - } - } - - - //! Assignment operator - aiBone &operator=(const aiBone& other) { - if (this == &other) { - return *this; - } - - mName = other.mName; - mNumWeights = other.mNumWeights; - mOffsetMatrix = other.mOffsetMatrix; - - if (other.mWeights && other.mNumWeights) - { - if (mWeights) { - delete[] mWeights; - } - - mWeights = new aiVertexWeight[mNumWeights]; - ::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight)); - } - - return *this; - } - - bool operator == ( const aiBone &rhs ) const { - if ( mName != rhs.mName || mNumWeights != rhs.mNumWeights ) { - return false; - } - - for ( size_t i = 0; i < mNumWeights; ++i ) { - if ( mWeights[ i ] != rhs.mWeights[ i ] ) { - return false; - } - } - - return true; - } - //! Destructor - deletes the array of vertex weights - ~aiBone() { - delete [] mWeights; - } -#endif // __cplusplus -}; - - -// --------------------------------------------------------------------------- -/** @brief Enumerates the types of geometric primitives supported by Assimp. - * - * @see aiFace Face data structure - * @see aiProcess_SortByPType Per-primitive sorting of meshes - * @see aiProcess_Triangulate Automatic triangulation - * @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types. - */ -enum aiPrimitiveType -{ - /** A point primitive. - * - * This is just a single vertex in the virtual world, - * #aiFace contains just one index for such a primitive. - */ - aiPrimitiveType_POINT = 0x1, - - /** A line primitive. - * - * This is a line defined through a start and an end position. - * #aiFace contains exactly two indices for such a primitive. - */ - aiPrimitiveType_LINE = 0x2, - - /** A triangular primitive. - * - * A triangle consists of three indices. - */ - aiPrimitiveType_TRIANGLE = 0x4, - - /** A higher-level polygon with more than 3 edges. - * - * A triangle is a polygon, but polygon in this context means - * "all polygons that are not triangles". The "Triangulate"-Step - * is provided for your convenience, it splits all polygons in - * triangles (which are much easier to handle). - */ - aiPrimitiveType_POLYGON = 0x8, - - - /** This value is not used. It is just here to force the - * compiler to map this enum to a 32 Bit integer. - */ -#ifndef SWIG - _aiPrimitiveType_Force32Bit = INT_MAX -#endif -}; //! enum aiPrimitiveType - -// Get the #aiPrimitiveType flag for a specific number of face indices -#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \ - ((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1))) - - - -// --------------------------------------------------------------------------- -/** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex - * animations for a particular frame. - * - * You may think of an #aiAnimMesh as a `patch` for the host mesh, which - * replaces only certain vertex data streams at a particular time. - * Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes). - * The actual relationship between the time line and anim meshes is - * established by #aiMeshAnim, which references singular mesh attachments - * by their ID and binds them to a time offset. -*/ -struct aiAnimMesh -{ - /**Anim Mesh name */ - C_STRUCT aiString mName; - - /** Replacement for aiMesh::mVertices. If this array is non-nullptr, - * it *must* contain mNumVertices entries. The corresponding - * array in the host mesh must be non-nullptr as well - animation - * meshes may neither add or nor remove vertex components (if - * a replacement array is nullptr and the corresponding source - * array is not, the source data is taken instead)*/ - C_STRUCT aiVector3D* mVertices; - - /** Replacement for aiMesh::mNormals. */ - C_STRUCT aiVector3D* mNormals; - - /** Replacement for aiMesh::mTangents. */ - C_STRUCT aiVector3D* mTangents; - - /** Replacement for aiMesh::mBitangents. */ - C_STRUCT aiVector3D* mBitangents; - - /** Replacement for aiMesh::mColors */ - C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS]; - - /** Replacement for aiMesh::mTextureCoords */ - C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - - /** The number of vertices in the aiAnimMesh, and thus the length of all - * the member arrays. - * - * This has always the same value as the mNumVertices property in the - * corresponding aiMesh. It is duplicated here merely to make the length - * of the member arrays accessible even if the aiMesh is not known, e.g. - * from language bindings. - */ - unsigned int mNumVertices; - - /** - * Weight of the AnimMesh. - */ - float mWeight; - -#ifdef __cplusplus - - aiAnimMesh() AI_NO_EXCEPT - : mVertices( nullptr ) - , mNormals(nullptr) - , mTangents(nullptr) - , mBitangents(nullptr) - , mColors() - , mTextureCoords() - , mNumVertices( 0 ) - , mWeight( 0.0f ) - { - // fixme consider moving this to the ctor initializer list as well - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){ - mTextureCoords[a] = nullptr; - } - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) { - mColors[a] = nullptr; - } - } - - ~aiAnimMesh() - { - delete [] mVertices; - delete [] mNormals; - delete [] mTangents; - delete [] mBitangents; - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { - delete [] mTextureCoords[a]; - } - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) { - delete [] mColors[a]; - } - } - - /** Check whether the anim mesh overrides the vertex positions - * of its host mesh*/ - bool HasPositions() const { - return mVertices != nullptr; - } - - /** Check whether the anim mesh overrides the vertex normals - * of its host mesh*/ - bool HasNormals() const { - return mNormals != nullptr; - } - - /** Check whether the anim mesh overrides the vertex tangents - * and bitangents of its host mesh. As for aiMesh, - * tangents and bitangents always go together. */ - bool HasTangentsAndBitangents() const { - return mTangents != nullptr; - } - - /** Check whether the anim mesh overrides a particular - * set of vertex colors on his host mesh. - * @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */ - bool HasVertexColors( unsigned int pIndex) const { - return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != nullptr; - } - - /** Check whether the anim mesh overrides a particular - * set of texture coordinates on his host mesh. - * @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */ - bool HasTextureCoords( unsigned int pIndex) const { - return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != nullptr; - } - -#endif -}; - -// --------------------------------------------------------------------------- -/** @brief Enumerates the methods of mesh morphing supported by Assimp. - */ -enum aiMorphingMethod -{ - /** Interpolation between morph targets */ - aiMorphingMethod_VERTEX_BLEND = 0x1, - - /** Normalized morphing between morph targets */ - aiMorphingMethod_MORPH_NORMALIZED = 0x2, - - /** Relative morphing between morph targets */ - aiMorphingMethod_MORPH_RELATIVE = 0x3, - - /** This value is not used. It is just here to force the - * compiler to map this enum to a 32 Bit integer. - */ -#ifndef SWIG - _aiMorphingMethod_Force32Bit = INT_MAX -#endif -}; //! enum aiMorphingMethod - -// --------------------------------------------------------------------------- -/** @brief A mesh represents a geometry or model with a single material. -* -* It usually consists of a number of vertices and a series of primitives/faces -* referencing the vertices. In addition there might be a series of bones, each -* of them addressing a number of vertices with a certain weight. Vertex data -* is presented in channels with each channel containing a single per-vertex -* information such as a set of texture coords or a normal vector. -* If a data pointer is non-null, the corresponding data stream is present. -* From C++-programs you can also use the comfort functions Has*() to -* test for the presence of various data streams. -* -* A Mesh uses only a single material which is referenced by a material ID. -* @note The mPositions member is usually not optional. However, vertex positions -* *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in -* @code -* aiScene::mFlags -* @endcode -*/ -struct aiMesh -{ - /** Bitwise combination of the members of the #aiPrimitiveType enum. - * This specifies which types of primitives are present in the mesh. - * The "SortByPrimitiveType"-Step can be used to make sure the - * output meshes consist of one primitive type each. - */ - unsigned int mPrimitiveTypes; - - /** The number of vertices in this mesh. - * This is also the size of all of the per-vertex data arrays. - * The maximum value for this member is #AI_MAX_VERTICES. - */ - unsigned int mNumVertices; - - /** The number of primitives (triangles, polygons, lines) in this mesh. - * This is also the size of the mFaces array. - * The maximum value for this member is #AI_MAX_FACES. - */ - unsigned int mNumFaces; - - /** Vertex positions. - * This array is always present in a mesh. The array is - * mNumVertices in size. - */ - C_STRUCT aiVector3D* mVertices; - - /** Vertex normals. - * The array contains normalized vectors, nullptr if not present. - * The array is mNumVertices in size. Normals are undefined for - * point and line primitives. A mesh consisting of points and - * lines only may not have normal vectors. Meshes with mixed - * primitive types (i.e. lines and triangles) may have normals, - * but the normals for vertices that are only referenced by - * point or line primitives are undefined and set to QNaN (WARN: - * qNaN compares to inequal to *everything*, even to qNaN itself. - * Using code like this to check whether a field is qnan is: - * @code - * #define IS_QNAN(f) (f != f) - * @endcode - * still dangerous because even 1.f == 1.f could evaluate to false! ( - * remember the subtleties of IEEE754 artithmetics). Use stuff like - * @c fpclassify instead. - * @note Normal vectors computed by Assimp are always unit-length. - * However, this needn't apply for normals that have been taken - * directly from the model file. - */ - C_STRUCT aiVector3D* mNormals; - - /** Vertex tangents. - * The tangent of a vertex points in the direction of the positive - * X texture axis. The array contains normalized vectors, nullptr if - * not present. The array is mNumVertices in size. A mesh consisting - * of points and lines only may not have normal vectors. Meshes with - * mixed primitive types (i.e. lines and triangles) may have - * normals, but the normals for vertices that are only referenced by - * point or line primitives are undefined and set to qNaN. See - * the #mNormals member for a detailed discussion of qNaNs. - * @note If the mesh contains tangents, it automatically also - * contains bitangents. - */ - C_STRUCT aiVector3D* mTangents; - - /** Vertex bitangents. - * The bitangent of a vertex points in the direction of the positive - * Y texture axis. The array contains normalized vectors, nullptr if not - * present. The array is mNumVertices in size. - * @note If the mesh contains tangents, it automatically also contains - * bitangents. - */ - C_STRUCT aiVector3D* mBitangents; - - /** Vertex color sets. - * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex - * colors per vertex. nullptr if not present. Each array is - * mNumVertices in size if present. - */ - C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS]; - - /** Vertex texture coords, also known as UV channels. - * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per - * vertex. nullptr if not present. The array is mNumVertices in size. - */ - C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - - /** Specifies the number of components for a given UV channel. - * Up to three channels are supported (UVW, for accessing volume - * or cube maps). If the value is 2 for a given channel n, the - * component p.z of mTextureCoords[n][p] is set to 0.0f. - * If the value is 1 for a given channel, p.y is set to 0.0f, too. - * @note 4D coords are not supported - */ - unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - - /** The faces the mesh is constructed from. - * Each face refers to a number of vertices by their indices. - * This array is always present in a mesh, its size is given - * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT - * is NOT set each face references an unique set of vertices. - */ - C_STRUCT aiFace* mFaces; - - /** The number of bones this mesh contains. - * Can be 0, in which case the mBones array is nullptr. - */ - unsigned int mNumBones; - - /** The bones of this mesh. - * A bone consists of a name by which it can be found in the - * frame hierarchy and a set of vertex weights. - */ - C_STRUCT aiBone** mBones; - - /** The material used by this mesh. - * A mesh uses only a single material. If an imported model uses - * multiple materials, the import splits up the mesh. Use this value - * as index into the scene's material list. - */ - unsigned int mMaterialIndex; - - /** Name of the mesh. Meshes can be named, but this is not a - * requirement and leaving this field empty is totally fine. - * There are mainly three uses for mesh names: - * - some formats name nodes and meshes independently. - * - importers tend to split meshes up to meet the - * one-material-per-mesh requirement. Assigning - * the same (dummy) name to each of the result meshes - * aids the caller at recovering the original mesh - * partitioning. - * - Vertex animations refer to meshes by their names. - **/ - C_STRUCT aiString mName; - - - /** The number of attachment meshes. Note! Currently only works with Collada loader. */ - unsigned int mNumAnimMeshes; - - /** Attachment meshes for this mesh, for vertex-based animation. - * Attachment meshes carry replacement data for some of the - * mesh'es vertex components (usually positions, normals). - * Note! Currently only works with Collada loader.*/ - C_STRUCT aiAnimMesh** mAnimMeshes; - - /** - * Method of morphing when animeshes are specified. - */ - unsigned int mMethod; - - /** - * - */ - C_STRUCT aiAABB mAABB; - -#ifdef __cplusplus - - //! Default constructor. Initializes all members to 0 - aiMesh() AI_NO_EXCEPT - : mPrimitiveTypes( 0 ) - , mNumVertices( 0 ) - , mNumFaces( 0 ) - , mVertices( nullptr ) - , mNormals(nullptr) - , mTangents(nullptr) - , mBitangents(nullptr) - , mColors() - , mTextureCoords() - , mNumUVComponents() - , mFaces(nullptr) - , mNumBones( 0 ) - , mBones(nullptr) - , mMaterialIndex( 0 ) - , mNumAnimMeshes( 0 ) - , mAnimMeshes(nullptr) - , mMethod( 0 ) - , mAABB() { - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) { - mNumUVComponents[a] = 0; - mTextureCoords[a] = nullptr; - } - - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) { - mColors[a] = nullptr; - } - } - - //! Deletes all storage allocated for the mesh - ~aiMesh() { - delete [] mVertices; - delete [] mNormals; - delete [] mTangents; - delete [] mBitangents; - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { - delete [] mTextureCoords[a]; - } - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) { - delete [] mColors[a]; - } - - // DO NOT REMOVE THIS ADDITIONAL CHECK - if (mNumBones && mBones) { - for( unsigned int a = 0; a < mNumBones; a++) { - if(mBones[a]) - { - delete mBones[a]; - } - } - delete [] mBones; - } - - if (mNumAnimMeshes && mAnimMeshes) { - for( unsigned int a = 0; a < mNumAnimMeshes; a++) { - delete mAnimMeshes[a]; - } - delete [] mAnimMeshes; - } - - delete [] mFaces; - } - - //! Check whether the mesh contains positions. Provided no special - //! scene flags are set, this will always be true - bool HasPositions() const - { return mVertices != nullptr && mNumVertices > 0; } - - //! Check whether the mesh contains faces. If no special scene flags - //! are set this should always return true - bool HasFaces() const - { return mFaces != nullptr && mNumFaces > 0; } - - //! Check whether the mesh contains normal vectors - bool HasNormals() const - { return mNormals != nullptr && mNumVertices > 0; } - - //! Check whether the mesh contains tangent and bitangent vectors - //! It is not possible that it contains tangents and no bitangents - //! (or the other way round). The existence of one of them - //! implies that the second is there, too. - bool HasTangentsAndBitangents() const - { return mTangents != nullptr && mBitangents != nullptr && mNumVertices > 0; } - - //! Check whether the mesh contains a vertex color set - //! \param pIndex Index of the vertex color set - bool HasVertexColors( unsigned int pIndex) const { - if (pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS) { - return false; - } else { - return mColors[pIndex] != nullptr && mNumVertices > 0; - } - } - - //! Check whether the mesh contains a texture coordinate set - //! \param pIndex Index of the texture coordinates set - bool HasTextureCoords( unsigned int pIndex) const { - if (pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { - return false; - } else { - return mTextureCoords[pIndex] != nullptr && mNumVertices > 0; - } - } - - //! Get the number of UV channels the mesh contains - unsigned int GetNumUVChannels() const { - unsigned int n( 0 ); - while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n]) { - ++n; - } - - return n; - } - - //! Get the number of vertex color channels the mesh contains - unsigned int GetNumColorChannels() const { - unsigned int n(0); - while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n]) { - ++n; - } - return n; - } - - //! Check whether the mesh contains bones - bool HasBones() const { - return mBones != nullptr && mNumBones > 0; - } - -#endif // __cplusplus -}; - -#ifdef __cplusplus -} -#endif //! extern "C" -#endif // AI_MESH_H_INC - diff --git a/thirdparty/assimp/include/assimp/metadata.h b/thirdparty/assimp/include/assimp/metadata.h deleted file mode 100644 index 849d90f485..0000000000 --- a/thirdparty/assimp/include/assimp/metadata.h +++ /dev/null @@ -1,384 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file metadata.h - * @brief Defines the data structures for holding node meta information. - */ -#pragma once -#ifndef AI_METADATA_H_INC -#define AI_METADATA_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#if defined(_MSC_VER) && (_MSC_VER <= 1500) -# include "Compiler/pstdint.h" -#else -# include <stdint.h> -#endif - -// ------------------------------------------------------------------------------- -/** - * Enum used to distinguish data types - */ - // ------------------------------------------------------------------------------- -typedef enum aiMetadataType { - AI_BOOL = 0, - AI_INT32 = 1, - AI_UINT64 = 2, - AI_FLOAT = 3, - AI_DOUBLE = 4, - AI_AISTRING = 5, - AI_AIVECTOR3D = 6, - AI_META_MAX = 7, - -#ifndef SWIG - FORCE_32BIT = INT_MAX -#endif -} aiMetadataType; - -// ------------------------------------------------------------------------------- -/** - * Metadata entry - * - * The type field uniquely identifies the underlying type of the data field - */ - // ------------------------------------------------------------------------------- -struct aiMetadataEntry { - aiMetadataType mType; - void* mData; -}; - -#ifdef __cplusplus - -#include <string> - -// ------------------------------------------------------------------------------- -/** - * Helper functions to get the aiType enum entry for a type - */ - // ------------------------------------------------------------------------------- - -inline aiMetadataType GetAiType( bool ) { return AI_BOOL; } -inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; } -inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; } -inline aiMetadataType GetAiType( float ) { return AI_FLOAT; } -inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; } -inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; } -inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; } - -#endif // __cplusplus - -// ------------------------------------------------------------------------------- -/** - * Container for holding metadata. - * - * Metadata is a key-value store using string keys and values. - */ - // ------------------------------------------------------------------------------- -struct aiMetadata { - /** Length of the mKeys and mValues arrays, respectively */ - unsigned int mNumProperties; - - /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */ - C_STRUCT aiString* mKeys; - - /** Arrays of values, may not be NULL. Entries in this array may be NULL if the - * corresponding property key has no assigned value. */ - C_STRUCT aiMetadataEntry* mValues; - -#ifdef __cplusplus - - /** - * @brief The default constructor, set all members to zero by default. - */ - aiMetadata() AI_NO_EXCEPT - : mNumProperties(0) - , mKeys(nullptr) - , mValues(nullptr) { - // empty - } - - aiMetadata( const aiMetadata &rhs ) - : mNumProperties( rhs.mNumProperties ) - , mKeys( nullptr ) - , mValues( nullptr ) { - mKeys = new aiString[ mNumProperties ]; - for ( size_t i = 0; i < static_cast<size_t>( mNumProperties ); ++i ) { - mKeys[ i ] = rhs.mKeys[ i ]; - } - mValues = new aiMetadataEntry[ mNumProperties ]; - for ( size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i ) { - mValues[ i ].mType = rhs.mValues[ i ].mType; - switch ( rhs.mValues[ i ].mType ) { - case AI_BOOL: - mValues[ i ].mData = new bool; - ::memcpy( mValues[ i ].mData, rhs.mValues[ i ].mData, sizeof(bool) ); - break; - case AI_INT32: { - int32_t v; - ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( int32_t ) ); - mValues[ i ].mData = new int32_t( v ); - } - break; - case AI_UINT64: { - uint64_t v; - ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( uint64_t ) ); - mValues[ i ].mData = new uint64_t( v ); - } - break; - case AI_FLOAT: { - float v; - ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( float ) ); - mValues[ i ].mData = new float( v ); - } - break; - case AI_DOUBLE: { - double v; - ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( double ) ); - mValues[ i ].mData = new double( v ); - } - break; - case AI_AISTRING: { - aiString v; - rhs.Get<aiString>( mKeys[ i ], v ); - mValues[ i ].mData = new aiString( v ); - } - break; - case AI_AIVECTOR3D: { - aiVector3D v; - rhs.Get<aiVector3D>( mKeys[ i ], v ); - mValues[ i ].mData = new aiVector3D( v ); - } - break; -#ifndef SWIG - case FORCE_32BIT: -#endif - default: - break; - } - - } - } - - /** - * @brief The destructor. - */ - ~aiMetadata() { - delete [] mKeys; - mKeys = nullptr; - if (mValues) { - // Delete each metadata entry - for (unsigned i=0; i<mNumProperties; ++i) { - void* data = mValues[i].mData; - switch (mValues[i].mType) { - case AI_BOOL: - delete static_cast< bool* >( data ); - break; - case AI_INT32: - delete static_cast< int32_t* >( data ); - break; - case AI_UINT64: - delete static_cast< uint64_t* >( data ); - break; - case AI_FLOAT: - delete static_cast< float* >( data ); - break; - case AI_DOUBLE: - delete static_cast< double* >( data ); - break; - case AI_AISTRING: - delete static_cast< aiString* >( data ); - break; - case AI_AIVECTOR3D: - delete static_cast< aiVector3D* >( data ); - break; -#ifndef SWIG - case FORCE_32BIT: -#endif - default: - break; - } - } - - // Delete the metadata array - delete [] mValues; - mValues = nullptr; - } - } - - /** - * @brief Allocates property fields + keys. - * @param numProperties Number of requested properties. - */ - static inline - aiMetadata *Alloc( unsigned int numProperties ) { - if ( 0 == numProperties ) { - return nullptr; - } - - aiMetadata *data = new aiMetadata; - data->mNumProperties = numProperties; - data->mKeys = new aiString[ data->mNumProperties ](); - data->mValues = new aiMetadataEntry[ data->mNumProperties ](); - - return data; - } - - /** - * @brief Deallocates property fields + keys. - */ - static inline - void Dealloc( aiMetadata *metadata ) { - delete metadata; - } - - template<typename T> - inline - void Add(const std::string& key, const T& value) { - aiString* new_keys = new aiString[mNumProperties + 1]; - aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1]; - - for(unsigned int i = 0; i < mNumProperties; ++i) - { - new_keys[i] = mKeys[i]; - new_values[i] = mValues[i]; - } - - delete mKeys; - delete mValues; - - mKeys = new_keys; - mValues = new_values; - - mNumProperties++; - - Set(mNumProperties - 1, key, value); - } - - template<typename T> - inline - bool Set( unsigned index, const std::string& key, const T& value ) { - // In range assertion - if ( index >= mNumProperties ) { - return false; - } - - // Ensure that we have a valid key. - if ( key.empty() ) { - return false; - } - - // Set metadata key - mKeys[index] = key; - - // Set metadata type - mValues[index].mType = GetAiType(value); - // Copy the given value to the dynamic storage - mValues[index].mData = new T(value); - - return true; - } - - template<typename T> - inline - bool Get( unsigned index, T& value ) const { - // In range assertion - if ( index >= mNumProperties ) { - return false; - } - - // Return false if the output data type does - // not match the found value's data type - if ( GetAiType( value ) != mValues[ index ].mType ) { - return false; - } - - // Otherwise, output the found value and - // return true - value = *static_cast<T*>(mValues[index].mData); - - return true; - } - - template<typename T> - inline - bool Get( const aiString& key, T& value ) const { - // Search for the given key - for ( unsigned int i = 0; i < mNumProperties; ++i ) { - if ( mKeys[ i ] == key ) { - return Get( i, value ); - } - } - return false; - } - - template<typename T> - inline - bool Get( const std::string& key, T& value ) const { - return Get(aiString(key), value); - } - - /// Return metadata entry for analyzing it by user. - /// \param [in] pIndex - index of the entry. - /// \param [out] pKey - pointer to the key value. - /// \param [out] pEntry - pointer to the entry: type and value. - /// \return false - if pIndex is out of range, else - true. - inline - bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) const { - if ( index >= mNumProperties ) { - return false; - } - - key = &mKeys[index]; - entry = &mValues[index]; - - return true; - } - -#endif // __cplusplus - -}; - -#endif // AI_METADATA_H_INC diff --git a/thirdparty/assimp/include/assimp/pbrmaterial.h b/thirdparty/assimp/include/assimp/pbrmaterial.h deleted file mode 100644 index 892a6347f7..0000000000 --- a/thirdparty/assimp/include/assimp/pbrmaterial.h +++ /dev/null @@ -1,80 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file pbrmaterial.h - * @brief Defines the material system of the library - */ -#pragma once -#ifndef AI_PBRMATERIAL_H_INC -#define AI_PBRMATERIAL_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0 -#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0 -#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0 -#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1 -#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0 -#define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0 -#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0 -#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0 -#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0 -#define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0 - -#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord" -#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname" -#define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid" -#define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag" -#define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin" -#define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale" -#define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength" - -#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD(type, N) _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N -#define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N -#define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N -#define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N -#define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N -#define AI_MATKEY_GLTF_TEXTURE_SCALE(type, N) _AI_MATKEY_GLTF_SCALE_BASE, type, N -#define AI_MATKEY_GLTF_TEXTURE_STRENGTH(type, N) _AI_MATKEY_GLTF_STRENGTH_BASE, type, N - -#endif //!!AI_PBRMATERIAL_H_INC diff --git a/thirdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h b/thirdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h deleted file mode 100644 index 41d8004877..0000000000 --- a/thirdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2016, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Android implementation of IOSystem using the standard C file functions. - * Aimed to ease the access to android assets */ - -#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) -#ifndef AI_ANDROIDJNIIOSYSTEM_H_INC -#define AI_ANDROIDJNIIOSYSTEM_H_INC - -#include <assimp/DefaultIOSystem.h> -#include <android/asset_manager.h> -#include <android/asset_manager_jni.h> -#include <android/native_activity.h> - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** Android extension to DefaultIOSystem using the standard C file functions */ -class ASSIMP_API AndroidJNIIOSystem : public DefaultIOSystem -{ -public: - - /** Initialize android activity data */ - std::string mApkWorkspacePath; - AAssetManager* mApkAssetManager; - - /** Constructor. */ - AndroidJNIIOSystem(ANativeActivity* activity); - - /** Destructor. */ - ~AndroidJNIIOSystem(); - - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ - bool Exists( const char* pFile) const; - - // ------------------------------------------------------------------- - /** Opens a file at the given path, with given mode */ - IOStream* Open( const char* strFile, const char* strMode); - - // ------------------------------------------------------------------------------------------------ - // Inits Android extractor - void AndroidActivityInit(ANativeActivity* activity); - - // ------------------------------------------------------------------------------------------------ - // Extracts android asset - bool AndroidExtractAsset(std::string name); - -}; - -} //!ns Assimp - -#endif //AI_ANDROIDJNIIOSYSTEM_H_INC -#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) diff --git a/thirdparty/assimp/include/assimp/postprocess.h b/thirdparty/assimp/include/assimp/postprocess.h deleted file mode 100644 index 4b6732e80a..0000000000 --- a/thirdparty/assimp/include/assimp/postprocess.h +++ /dev/null @@ -1,703 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file postprocess.h - * @brief Definitions for import post processing steps - */ -#pragma once -#ifndef AI_POSTPROCESS_H_INC -#define AI_POSTPROCESS_H_INC - -#include <assimp/types.h> - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// ----------------------------------------------------------------------------------- -/** @enum aiPostProcessSteps - * @brief Defines the flags for all possible post processing steps. - * - * @note Some steps are influenced by properties set on the Assimp::Importer itself - * - * @see Assimp::Importer::ReadFile() - * @see Assimp::Importer::SetPropertyInteger() - * @see aiImportFile - * @see aiImportFileEx - */ -// ----------------------------------------------------------------------------------- -enum aiPostProcessSteps -{ - - // ------------------------------------------------------------------------- - /** <hr>Calculates the tangents and bitangents for the imported meshes. - * - * Does nothing if a mesh does not have normals. You might want this post - * processing step to be executed if you plan to use tangent space calculations - * such as normal mapping applied to the meshes. There's an importer property, - * <tt>#AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE</tt>, which allows you to specify - * a maximum smoothing angle for the algorithm. However, usually you'll - * want to leave it at the default value. - */ - aiProcess_CalcTangentSpace = 0x1, - - // ------------------------------------------------------------------------- - /** <hr>Identifies and joins identical vertex data sets within all - * imported meshes. - * - * After this step is run, each mesh contains unique vertices, - * so a vertex may be used by multiple faces. You usually want - * to use this post processing step. If your application deals with - * indexed geometry, this step is compulsory or you'll just waste rendering - * time. <b>If this flag is not specified</b>, no vertices are referenced by - * more than one face and <b>no index buffer is required</b> for rendering. - */ - aiProcess_JoinIdenticalVertices = 0x2, - - // ------------------------------------------------------------------------- - /** <hr>Converts all the imported data to a left-handed coordinate space. - * - * By default the data is returned in a right-handed coordinate space (which - * OpenGL prefers). In this space, +X points to the right, - * +Z points towards the viewer, and +Y points upwards. In the DirectX - * coordinate space +X points to the right, +Y points upwards, and +Z points - * away from the viewer. - * - * You'll probably want to consider this flag if you use Direct3D for - * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this - * setting and bundles all conversions typically required for D3D-based - * applications. - */ - aiProcess_MakeLeftHanded = 0x4, - - // ------------------------------------------------------------------------- - /** <hr>Triangulates all faces of all meshes. - * - * By default the imported mesh data might contain faces with more than 3 - * indices. For rendering you'll usually want all faces to be triangles. - * This post processing step splits up faces with more than 3 indices into - * triangles. Line and point primitives are *not* modified! If you want - * 'triangles only' with no other kinds of primitives, try the following - * solution: - * <ul> - * <li>Specify both #aiProcess_Triangulate and #aiProcess_SortByPType </li> - * <li>Ignore all point and line meshes when you process assimp's output</li> - * </ul> - */ - aiProcess_Triangulate = 0x8, - - // ------------------------------------------------------------------------- - /** <hr>Removes some parts of the data structure (animations, materials, - * light sources, cameras, textures, vertex components). - * - * The components to be removed are specified in a separate - * importer property, <tt>#AI_CONFIG_PP_RVC_FLAGS</tt>. This is quite useful - * if you don't need all parts of the output structure. Vertex colors - * are rarely used today for example... Calling this step to remove unneeded - * data from the pipeline as early as possible results in increased - * performance and a more optimized output data structure. - * This step is also useful if you want to force Assimp to recompute - * normals or tangents. The corresponding steps don't recompute them if - * they're already there (loaded from the source asset). By using this - * step you can make sure they are NOT there. - * - * This flag is a poor one, mainly because its purpose is usually - * misunderstood. Consider the following case: a 3D model has been exported - * from a CAD app, and it has per-face vertex colors. Vertex positions can't be - * shared, thus the #aiProcess_JoinIdenticalVertices step fails to - * optimize the data because of these nasty little vertex colors. - * Most apps don't even process them, so it's all for nothing. By using - * this step, unneeded components are excluded as early as possible - * thus opening more room for internal optimizations. - */ - aiProcess_RemoveComponent = 0x10, - - // ------------------------------------------------------------------------- - /** <hr>Generates normals for all faces of all meshes. - * - * This is ignored if normals are already there at the time this flag - * is evaluated. Model importers try to load them from the source file, so - * they're usually already there. Face normals are shared between all points - * of a single face, so a single point can have multiple normals, which - * forces the library to duplicate vertices in some cases. - * #aiProcess_JoinIdenticalVertices is *senseless* then. - * - * This flag may not be specified together with #aiProcess_GenSmoothNormals. - */ - aiProcess_GenNormals = 0x20, - - // ------------------------------------------------------------------------- - /** <hr>Generates smooth normals for all vertices in the mesh. - * - * This is ignored if normals are already there at the time this flag - * is evaluated. Model importers try to load them from the source file, so - * they're usually already there. - * - * This flag may not be specified together with - * #aiProcess_GenNormals. There's a importer property, - * <tt>#AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE</tt> which allows you to specify - * an angle maximum for the normal smoothing algorithm. Normals exceeding - * this limit are not smoothed, resulting in a 'hard' seam between two faces. - * Using a decent angle here (e.g. 80 degrees) results in very good visual - * appearance. - */ - aiProcess_GenSmoothNormals = 0x40, - - // ------------------------------------------------------------------------- - /** <hr>Splits large meshes into smaller sub-meshes. - * - * This is quite useful for real-time rendering, where the number of triangles - * which can be maximally processed in a single draw-call is limited - * by the video driver/hardware. The maximum vertex buffer is usually limited - * too. Both requirements can be met with this step: you may specify both a - * triangle and vertex limit for a single mesh. - * - * The split limits can (and should!) be set through the - * <tt>#AI_CONFIG_PP_SLM_VERTEX_LIMIT</tt> and <tt>#AI_CONFIG_PP_SLM_TRIANGLE_LIMIT</tt> - * importer properties. The default values are <tt>#AI_SLM_DEFAULT_MAX_VERTICES</tt> and - * <tt>#AI_SLM_DEFAULT_MAX_TRIANGLES</tt>. - * - * Note that splitting is generally a time-consuming task, but only if there's - * something to split. The use of this step is recommended for most users. - */ - aiProcess_SplitLargeMeshes = 0x80, - - // ------------------------------------------------------------------------- - /** <hr>Removes the node graph and pre-transforms all vertices with - * the local transformation matrices of their nodes. - * - * The output scene still contains nodes, however there is only a - * root node with children, each one referencing only one mesh, - * and each mesh referencing one material. For rendering, you can - * simply render all meshes in order - you don't need to pay - * attention to local transformations and the node hierarchy. - * Animations are removed during this step. - * This step is intended for applications without a scenegraph. - * The step CAN cause some problems: if e.g. a mesh of the asset - * contains normals and another, using the same material index, does not, - * they will be brought together, but the first meshes's part of - * the normal list is zeroed. However, these artifacts are rare. - * @note The <tt>#AI_CONFIG_PP_PTV_NORMALIZE</tt> configuration property - * can be set to normalize the scene's spatial dimension to the -1...1 - * range. - */ - aiProcess_PreTransformVertices = 0x100, - - // ------------------------------------------------------------------------- - /** <hr>Limits the number of bones simultaneously affecting a single vertex - * to a maximum value. - * - * If any vertex is affected by more than the maximum number of bones, the least - * important vertex weights are removed and the remaining vertex weights are - * renormalized so that the weights still sum up to 1. - * The default bone weight limit is 4 (defined as <tt>#AI_LMW_MAX_WEIGHTS</tt> in - * config.h), but you can use the <tt>#AI_CONFIG_PP_LBW_MAX_WEIGHTS</tt> importer - * property to supply your own limit to the post processing step. - * - * If you intend to perform the skinning in hardware, this post processing - * step might be of interest to you. - */ - aiProcess_LimitBoneWeights = 0x200, - - // ------------------------------------------------------------------------- - /** <hr>Validates the imported scene data structure. - * This makes sure that all indices are valid, all animations and - * bones are linked correctly, all material references are correct .. etc. - * - * It is recommended that you capture Assimp's log output if you use this flag, - * so you can easily find out what's wrong if a file fails the - * validation. The validator is quite strict and will find *all* - * inconsistencies in the data structure... It is recommended that plugin - * developers use it to debug their loaders. There are two types of - * validation failures: - * <ul> - * <li>Error: There's something wrong with the imported data. Further - * postprocessing is not possible and the data is not usable at all. - * The import fails. #Importer::GetErrorString() or #aiGetErrorString() - * carry the error message around.</li> - * <li>Warning: There are some minor issues (e.g. 1000000 animation - * keyframes with the same time), but further postprocessing and use - * of the data structure is still safe. Warning details are written - * to the log file, <tt>#AI_SCENE_FLAGS_VALIDATION_WARNING</tt> is set - * in #aiScene::mFlags</li> - * </ul> - * - * This post-processing step is not time-consuming. Its use is not - * compulsory, but recommended. - */ - aiProcess_ValidateDataStructure = 0x400, - - // ------------------------------------------------------------------------- - /** <hr>Reorders triangles for better vertex cache locality. - * - * The step tries to improve the ACMR (average post-transform vertex cache - * miss ratio) for all meshes. The implementation runs in O(n) and is - * roughly based on the 'tipsify' algorithm (see <a href=" - * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf">this - * paper</a>). - * - * If you intend to render huge models in hardware, this step might - * be of interest to you. The <tt>#AI_CONFIG_PP_ICL_PTCACHE_SIZE</tt> - * importer property can be used to fine-tune the cache optimization. - */ - aiProcess_ImproveCacheLocality = 0x800, - - // ------------------------------------------------------------------------- - /** <hr>Searches for redundant/unreferenced materials and removes them. - * - * This is especially useful in combination with the - * #aiProcess_PreTransformVertices and #aiProcess_OptimizeMeshes flags. - * Both join small meshes with equal characteristics, but they can't do - * their work if two meshes have different materials. Because several - * material settings are lost during Assimp's import filters, - * (and because many exporters don't check for redundant materials), huge - * models often have materials which are are defined several times with - * exactly the same settings. - * - * Several material settings not contributing to the final appearance of - * a surface are ignored in all comparisons (e.g. the material name). - * So, if you're passing additional information through the - * content pipeline (probably using *magic* material names), don't - * specify this flag. Alternatively take a look at the - * <tt>#AI_CONFIG_PP_RRM_EXCLUDE_LIST</tt> importer property. - */ - aiProcess_RemoveRedundantMaterials = 0x1000, - - // ------------------------------------------------------------------------- - /** <hr>This step tries to determine which meshes have normal vectors - * that are facing inwards and inverts them. - * - * The algorithm is simple but effective: - * the bounding box of all vertices + their normals is compared against - * the volume of the bounding box of all vertices without their normals. - * This works well for most objects, problems might occur with planar - * surfaces. However, the step tries to filter such cases. - * The step inverts all in-facing normals. Generally it is recommended - * to enable this step, although the result is not always correct. - */ - aiProcess_FixInfacingNormals = 0x2000, - - - - // ------------------------------------------------------------------------- - /** - * This step generically populates aiBone->mArmature and aiBone->mNode generically - * The point of these is it saves you later having to calculate these elements - * This is useful when handling rest information or skin information - * If you have multiple armatures on your models we strongly recommend enabling this - * Instead of writing your own multi-root, multi-armature lookups we have done the - * hard work for you :) - */ - aiProcess_PopulateArmatureData = 0x4000, - - // ------------------------------------------------------------------------- - /** <hr>This step splits meshes with more than one primitive type in - * homogeneous sub-meshes. - * - * The step is executed after the triangulation step. After the step - * returns, just one bit is set in aiMesh::mPrimitiveTypes. This is - * especially useful for real-time rendering where point and line - * primitives are often ignored or rendered separately. - * You can use the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to - * specify which primitive types you need. This can be used to easily - * exclude lines and points, which are rarely used, from the import. - */ - aiProcess_SortByPType = 0x8000, - - // ------------------------------------------------------------------------- - /** <hr>This step searches all meshes for degenerate primitives and - * converts them to proper lines or points. - * - * A face is 'degenerate' if one or more of its points are identical. - * To have the degenerate stuff not only detected and collapsed but - * removed, try one of the following procedures: - * <br><b>1.</b> (if you support lines and points for rendering but don't - * want the degenerates)<br> - * <ul> - * <li>Specify the #aiProcess_FindDegenerates flag. - * </li> - * <li>Set the <tt>#AI_CONFIG_PP_FD_REMOVE</tt> importer property to - * 1. This will cause the step to remove degenerate triangles from the - * import as soon as they're detected. They won't pass any further - * pipeline steps. - * </li> - * </ul> - * <br><b>2.</b>(if you don't support lines and points at all)<br> - * <ul> - * <li>Specify the #aiProcess_FindDegenerates flag. - * </li> - * <li>Specify the #aiProcess_SortByPType flag. This moves line and - * point primitives to separate meshes. - * </li> - * <li>Set the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to - * @code aiPrimitiveType_POINTS | aiPrimitiveType_LINES - * @endcode to cause SortByPType to reject point - * and line meshes from the scene. - * </li> - * </ul> - * - * This step also removes very small triangles with a surface area smaller - * than 10^-6. If you rely on having these small triangles, or notice holes - * in your model, set the property <tt>#AI_CONFIG_PP_FD_CHECKAREA</tt> to - * false. - * @note Degenerate polygons are not necessarily evil and that's why - * they're not removed by default. There are several file formats which - * don't support lines or points, and some exporters bypass the - * format specification and write them as degenerate triangles instead. - */ - aiProcess_FindDegenerates = 0x10000, - - // ------------------------------------------------------------------------- - /** <hr>This step searches all meshes for invalid data, such as zeroed - * normal vectors or invalid UV coords and removes/fixes them. This is - * intended to get rid of some common exporter errors. - * - * This is especially useful for normals. If they are invalid, and - * the step recognizes this, they will be removed and can later - * be recomputed, i.e. by the #aiProcess_GenSmoothNormals flag.<br> - * The step will also remove meshes that are infinitely small and reduce - * animation tracks consisting of hundreds if redundant keys to a single - * key. The <tt>AI_CONFIG_PP_FID_ANIM_ACCURACY</tt> config property decides - * the accuracy of the check for duplicate animation tracks. - */ - aiProcess_FindInvalidData = 0x20000, - - // ------------------------------------------------------------------------- - /** <hr>This step converts non-UV mappings (such as spherical or - * cylindrical mapping) to proper texture coordinate channels. - * - * Most applications will support UV mapping only, so you will - * probably want to specify this step in every case. Note that Assimp is not - * always able to match the original mapping implementation of the - * 3D app which produced a model perfectly. It's always better to let the - * modelling app compute the UV channels - 3ds max, Maya, Blender, - * LightWave, and Modo do this for example. - * - * @note If this step is not requested, you'll need to process the - * <tt>#AI_MATKEY_MAPPING</tt> material property in order to display all assets - * properly. - */ - aiProcess_GenUVCoords = 0x40000, - - // ------------------------------------------------------------------------- - /** <hr>This step applies per-texture UV transformations and bakes - * them into stand-alone vtexture coordinate channels. - * - * UV transformations are specified per-texture - see the - * <tt>#AI_MATKEY_UVTRANSFORM</tt> material key for more information. - * This step processes all textures with - * transformed input UV coordinates and generates a new (pre-transformed) UV channel - * which replaces the old channel. Most applications won't support UV - * transformations, so you will probably want to specify this step. - * - * @note UV transformations are usually implemented in real-time apps by - * transforming texture coordinates at vertex shader stage with a 3x3 - * (homogenous) transformation matrix. - */ - aiProcess_TransformUVCoords = 0x80000, - - // ------------------------------------------------------------------------- - /** <hr>This step searches for duplicate meshes and replaces them - * with references to the first mesh. - * - * This step takes a while, so don't use it if speed is a concern. - * Its main purpose is to workaround the fact that many export - * file formats don't support instanced meshes, so exporters need to - * duplicate meshes. This step removes the duplicates again. Please - * note that Assimp does not currently support per-node material - * assignment to meshes, which means that identical meshes with - * different materials are currently *not* joined, although this is - * planned for future versions. - */ - aiProcess_FindInstances = 0x100000, - - // ------------------------------------------------------------------------- - /** <hr>A post-processing step to reduce the number of meshes. - * - * This will, in fact, reduce the number of draw calls. - * - * This is a very effective optimization and is recommended to be used - * together with #aiProcess_OptimizeGraph, if possible. The flag is fully - * compatible with both #aiProcess_SplitLargeMeshes and #aiProcess_SortByPType. - */ - aiProcess_OptimizeMeshes = 0x200000, - - - // ------------------------------------------------------------------------- - /** <hr>A post-processing step to optimize the scene hierarchy. - * - * Nodes without animations, bones, lights or cameras assigned are - * collapsed and joined. - * - * Node names can be lost during this step. If you use special 'tag nodes' - * to pass additional information through your content pipeline, use the - * <tt>#AI_CONFIG_PP_OG_EXCLUDE_LIST</tt> importer property to specify a - * list of node names you want to be kept. Nodes matching one of the names - * in this list won't be touched or modified. - * - * Use this flag with caution. Most simple files will be collapsed to a - * single node, so complex hierarchies are usually completely lost. This is not - * useful for editor environments, but probably a very effective - * optimization if you just want to get the model data, convert it to your - * own format, and render it as fast as possible. - * - * This flag is designed to be used with #aiProcess_OptimizeMeshes for best - * results. - * - * @note 'Crappy' scenes with thousands of extremely small meshes packed - * in deeply nested nodes exist for almost all file formats. - * #aiProcess_OptimizeMeshes in combination with #aiProcess_OptimizeGraph - * usually fixes them all and makes them renderable. - */ - aiProcess_OptimizeGraph = 0x400000, - - // ------------------------------------------------------------------------- - /** <hr>This step flips all UV coordinates along the y-axis and adjusts - * material settings and bitangents accordingly. - * - * <b>Output UV coordinate system:</b> - * @code - * 0y|0y ---------- 1x|0y - * | | - * | | - * | | - * 0x|1y ---------- 1x|1y - * @endcode - * - * You'll probably want to consider this flag if you use Direct3D for - * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this - * setting and bundles all conversions typically required for D3D-based - * applications. - */ - aiProcess_FlipUVs = 0x800000, - - // ------------------------------------------------------------------------- - /** <hr>This step adjusts the output face winding order to be CW. - * - * The default face winding order is counter clockwise (CCW). - * - * <b>Output face order:</b> - * @code - * x2 - * - * x0 - * x1 - * @endcode - */ - aiProcess_FlipWindingOrder = 0x1000000, - - // ------------------------------------------------------------------------- - /** <hr>This step splits meshes with many bones into sub-meshes so that each - * sub-mesh has fewer or as many bones as a given limit. - */ - aiProcess_SplitByBoneCount = 0x2000000, - - // ------------------------------------------------------------------------- - /** <hr>This step removes bones losslessly or according to some threshold. - * - * In some cases (i.e. formats that require it) exporters are forced to - * assign dummy bone weights to otherwise static meshes assigned to - * animated meshes. Full, weight-based skinning is expensive while - * animating nodes is extremely cheap, so this step is offered to clean up - * the data in that regard. - * - * Use <tt>#AI_CONFIG_PP_DB_THRESHOLD</tt> to control this. - * Use <tt>#AI_CONFIG_PP_DB_ALL_OR_NONE</tt> if you want bones removed if and - * only if all bones within the scene qualify for removal. - */ - aiProcess_Debone = 0x4000000, - - - - // ------------------------------------------------------------------------- - /** <hr>This step will perform a global scale of the model. - * - * Some importers are providing a mechanism to define a scaling unit for the - * model. This post processing step can be used to do so. You need to get the - * global scaling from your importer settings like in FBX. Use the flag - * AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY from the global property table to configure this. - * - * Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to setup the global scaling factor. - */ - aiProcess_GlobalScale = 0x8000000, - - // ------------------------------------------------------------------------- - /** <hr>A postprocessing step to embed of textures. - * - * This will remove external data dependencies for textures. - * If a texture's file does not exist at the specified path - * (due, for instance, to an absolute path generated on another system), - * it will check if a file with the same name exists at the root folder - * of the imported model. And if so, it uses that. - */ - aiProcess_EmbedTextures = 0x10000000, - - // aiProcess_GenEntityMeshes = 0x100000, - // aiProcess_OptimizeAnimations = 0x200000 - // aiProcess_FixTexturePaths = 0x200000 - - - aiProcess_ForceGenNormals = 0x20000000, - - // ------------------------------------------------------------------------- - /** <hr>Drops normals for all faces of all meshes. - * - * This is ignored if no normals are present. - * Face normals are shared between all points of a single face, - * so a single point can have multiple normals, which - * forces the library to duplicate vertices in some cases. - * #aiProcess_JoinIdenticalVertices is *senseless* then. - * This process gives sense back to aiProcess_JoinIdenticalVertices - */ - aiProcess_DropNormals = 0x40000000, - - // ------------------------------------------------------------------------- - /** - */ - aiProcess_GenBoundingBoxes = 0x80000000 -}; - - -// --------------------------------------------------------------------------------------- -/** @def aiProcess_ConvertToLeftHanded - * @brief Shortcut flag for Direct3D-based applications. - * - * Supersedes the #aiProcess_MakeLeftHanded and #aiProcess_FlipUVs and - * #aiProcess_FlipWindingOrder flags. - * The output data matches Direct3D's conventions: left-handed geometry, upper-left - * origin for UV coordinates and finally clockwise face order, suitable for CCW culling. - * - * @deprecated - */ -#define aiProcess_ConvertToLeftHanded ( \ - aiProcess_MakeLeftHanded | \ - aiProcess_FlipUVs | \ - aiProcess_FlipWindingOrder | \ - 0 ) - - -// --------------------------------------------------------------------------------------- -/** @def aiProcessPreset_TargetRealtime_Fast - * @brief Default postprocess configuration optimizing the data for real-time rendering. - * - * Applications would want to use this preset to load models on end-user PCs, - * maybe for direct use in game. - * - * If you're using DirectX, don't forget to combine this value with - * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations - * in your application apply the #aiProcess_TransformUVCoords step, too. - * @note Please take the time to read the docs for the steps enabled by this preset. - * Some of them offer further configurable properties, while some of them might not be of - * use for you so it might be better to not specify them. - */ -#define aiProcessPreset_TargetRealtime_Fast ( \ - aiProcess_CalcTangentSpace | \ - aiProcess_GenNormals | \ - aiProcess_JoinIdenticalVertices | \ - aiProcess_Triangulate | \ - aiProcess_GenUVCoords | \ - aiProcess_SortByPType | \ - 0 ) - - // --------------------------------------------------------------------------------------- - /** @def aiProcessPreset_TargetRealtime_Quality - * @brief Default postprocess configuration optimizing the data for real-time rendering. - * - * Unlike #aiProcessPreset_TargetRealtime_Fast, this configuration - * performs some extra optimizations to improve rendering speed and - * to minimize memory usage. It could be a good choice for a level editor - * environment where import speed is not so important. - * - * If you're using DirectX, don't forget to combine this value with - * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations - * in your application apply the #aiProcess_TransformUVCoords step, too. - * @note Please take the time to read the docs for the steps enabled by this preset. - * Some of them offer further configurable properties, while some of them might not be - * of use for you so it might be better to not specify them. - */ -#define aiProcessPreset_TargetRealtime_Quality ( \ - aiProcess_CalcTangentSpace | \ - aiProcess_GenSmoothNormals | \ - aiProcess_JoinIdenticalVertices | \ - aiProcess_ImproveCacheLocality | \ - aiProcess_LimitBoneWeights | \ - aiProcess_RemoveRedundantMaterials | \ - aiProcess_SplitLargeMeshes | \ - aiProcess_Triangulate | \ - aiProcess_GenUVCoords | \ - aiProcess_SortByPType | \ - aiProcess_FindDegenerates | \ - aiProcess_FindInvalidData | \ - 0 ) - - // --------------------------------------------------------------------------------------- - /** @def aiProcessPreset_TargetRealtime_MaxQuality - * @brief Default postprocess configuration optimizing the data for real-time rendering. - * - * This preset enables almost every optimization step to achieve perfectly - * optimized data. It's your choice for level editor environments where import speed - * is not important. - * - * If you're using DirectX, don't forget to combine this value with - * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations - * in your application, apply the #aiProcess_TransformUVCoords step, too. - * @note Please take the time to read the docs for the steps enabled by this preset. - * Some of them offer further configurable properties, while some of them might not be - * of use for you so it might be better to not specify them. - */ -#define aiProcessPreset_TargetRealtime_MaxQuality ( \ - aiProcessPreset_TargetRealtime_Quality | \ - aiProcess_FindInstances | \ - aiProcess_ValidateDataStructure | \ - aiProcess_OptimizeMeshes | \ - 0 ) - - -#ifdef __cplusplus -} // end of extern "C" -#endif - -#endif // AI_POSTPROCESS_H_INC diff --git a/thirdparty/assimp/include/assimp/qnan.h b/thirdparty/assimp/include/assimp/qnan.h deleted file mode 100644 index 06780da5b8..0000000000 --- a/thirdparty/assimp/include/assimp/qnan.h +++ /dev/null @@ -1,162 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file qnan.h - * @brief Some utilities for our dealings with qnans. - * - * @note Some loaders use qnans to mark invalid values tempoarily, also - * Assimp explicitly enforces undefined normals to be set to qnan. - * qnan utilities are available in standard libraries (C99 for example) - * but last time I checked compiler coverage was so bad that I decided - * to reinvent the wheel. - */ -#pragma once -#ifndef AI_QNAN_H_INCLUDED -#define AI_QNAN_H_INCLUDED - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/defs.h> - -#include <limits> -#include <stdint.h> - -// --------------------------------------------------------------------------- -/** Data structure to represent the bit pattern of a 32 Bit - * IEEE 754 floating-point number. */ -union _IEEESingle { - float Float; - struct - { - uint32_t Frac : 23; - uint32_t Exp : 8; - uint32_t Sign : 1; - } IEEE; -}; - -// --------------------------------------------------------------------------- -/** Data structure to represent the bit pattern of a 64 Bit - * IEEE 754 floating-point number. */ -union _IEEEDouble { - double Double; - struct - { - uint64_t Frac : 52; - uint64_t Exp : 11; - uint64_t Sign : 1; - } IEEE; -}; - -// --------------------------------------------------------------------------- -/** Check whether a given float is qNaN. - * @param in Input value */ -AI_FORCE_INLINE bool is_qnan(float in) { - // the straightforward solution does not work: - // return (in != in); - // compiler generates code like this - // load <in> to <register-with-different-width> - // compare <register-with-different-width> against <in> - - // FIXME: Use <float> stuff instead? I think fpclassify needs C99 - _IEEESingle temp; - memcpy(&temp, &in, sizeof(float)); - return (temp.IEEE.Exp == (1u << 8)-1 && - temp.IEEE.Frac); -} - -// --------------------------------------------------------------------------- -/** Check whether a given double is qNaN. - * @param in Input value */ -AI_FORCE_INLINE bool is_qnan(double in) { - // the straightforward solution does not work: - // return (in != in); - // compiler generates code like this - // load <in> to <register-with-different-width> - // compare <register-with-different-width> against <in> - - // FIXME: Use <float> stuff instead? I think fpclassify needs C99 - _IEEEDouble temp; - memcpy(&temp, &in, sizeof(in)); - return (temp.IEEE.Exp == (1u << 11)-1 && - temp.IEEE.Frac); -} - -// --------------------------------------------------------------------------- -/** @brief check whether a float is either NaN or (+/-) INF. - * - * Denorms return false, they're treated like normal values. - * @param in Input value */ -AI_FORCE_INLINE bool is_special_float(float in) { - _IEEESingle temp; - memcpy(&temp, &in, sizeof(float)); - return (temp.IEEE.Exp == (1u << 8)-1); -} - -// --------------------------------------------------------------------------- -/** @brief check whether a double is either NaN or (+/-) INF. - * - * Denorms return false, they're treated like normal values. - * @param in Input value */ -AI_FORCE_INLINE bool is_special_float(double in) { - _IEEESingle temp; - memcpy(&temp, &in, sizeof(float)); - return (temp.IEEE.Exp == (1u << 11)-1); -} - -// --------------------------------------------------------------------------- -/** Check whether a float is NOT qNaN. - * @param in Input value */ -template<class TReal> -AI_FORCE_INLINE bool is_not_qnan(TReal in) { - return !is_qnan(in); -} - -// --------------------------------------------------------------------------- -/** @brief Get a fresh qnan. */ -AI_FORCE_INLINE ai_real get_qnan() { - return std::numeric_limits<ai_real>::quiet_NaN(); -} - -#endif // !! AI_QNAN_H_INCLUDED diff --git a/thirdparty/assimp/include/assimp/quaternion.h b/thirdparty/assimp/include/assimp/quaternion.h deleted file mode 100644 index ae45959b41..0000000000 --- a/thirdparty/assimp/include/assimp/quaternion.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file quaternion.h - * @brief Quaternion structure, including operators when compiling in C++ - */ -#pragma once -#ifndef AI_QUATERNION_H_INC -#define AI_QUATERNION_H_INC - -#ifdef __cplusplus - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/defs.h> - -template <typename TReal> class aiVector3t; -template <typename TReal> class aiMatrix3x3t; - -// --------------------------------------------------------------------------- -/** Represents a quaternion in a 4D vector. */ -template <typename TReal> -class aiQuaterniont -{ -public: - aiQuaterniont() AI_NO_EXCEPT : w(1.0), x(), y(), z() {} - aiQuaterniont(TReal pw, TReal px, TReal py, TReal pz) - : w(pw), x(px), y(py), z(pz) {} - - /** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */ - explicit aiQuaterniont( const aiMatrix3x3t<TReal>& pRotMatrix); - - /** Construct from euler angles */ - aiQuaterniont( TReal rotx, TReal roty, TReal rotz); - - /** Construct from an axis-angle pair */ - aiQuaterniont( aiVector3t<TReal> axis, TReal angle); - - /** Construct from a normalized quaternion stored in a vec3 */ - explicit aiQuaterniont( aiVector3t<TReal> normalized); - - /** Returns a matrix representation of the quaternion */ - aiMatrix3x3t<TReal> GetMatrix() const; - -public: - - bool operator== (const aiQuaterniont& o) const; - bool operator!= (const aiQuaterniont& o) const; - - bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const; - -public: - - /** Normalize the quaternion */ - aiQuaterniont& Normalize(); - - /** Compute quaternion conjugate */ - aiQuaterniont& Conjugate (); - - /** Rotate a point by this quaternion */ - aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in); - - /** Multiply two quaternions */ - aiQuaterniont operator* (const aiQuaterniont& two) const; - -public: - - /** Performs a spherical interpolation between two quaternions and writes the result into the third. - * @param pOut Target object to received the interpolated rotation. - * @param pStart Start rotation of the interpolation at factor == 0. - * @param pEnd End rotation, factor == 1. - * @param pFactor Interpolation factor between 0 and 1. Values outside of this range yield undefined results. - */ - static void Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, - const aiQuaterniont& pEnd, TReal pFactor); - -public: - - //! w,x,y,z components of the quaternion - TReal w, x, y, z; -} ; - -typedef aiQuaterniont<ai_real> aiQuaternion; - -#else - -struct aiQuaternion { - ai_real w, x, y, z; -}; - -#endif - -#endif // AI_QUATERNION_H_INC diff --git a/thirdparty/assimp/include/assimp/quaternion.inl b/thirdparty/assimp/include/assimp/quaternion.inl deleted file mode 100644 index 3ce514d1bb..0000000000 --- a/thirdparty/assimp/include/assimp/quaternion.inl +++ /dev/null @@ -1,290 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file quaternion.inl - * @brief Inline implementation of aiQuaterniont<TReal> operators - */ -#pragma once -#ifndef AI_QUATERNION_INL_INC -#define AI_QUATERNION_INL_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -#include <assimp/quaternion.h> - -#include <cmath> - -// --------------------------------------------------------------------------- -template<typename TReal> -bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const -{ - return x == o.x && y == o.y && z == o.z && w == o.w; -} - -// --------------------------------------------------------------------------- -template<typename TReal> -bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const -{ - return !(*this == o); -} - -// --------------------------------------------------------------------------- -template<typename TReal> -inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, TReal epsilon) const { - return - std::abs(x - o.x) <= epsilon && - std::abs(y - o.y) <= epsilon && - std::abs(z - o.z) <= epsilon && - std::abs(w - o.w) <= epsilon; -} - -// --------------------------------------------------------------------------- -// Constructs a quaternion from a rotation matrix -template<typename TReal> -inline aiQuaterniont<TReal>::aiQuaterniont( const aiMatrix3x3t<TReal> &pRotMatrix) -{ - TReal t = pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3; - - // large enough - if( t > static_cast<TReal>(0)) - { - TReal s = std::sqrt(1 + t) * static_cast<TReal>(2.0); - x = (pRotMatrix.c2 - pRotMatrix.b3) / s; - y = (pRotMatrix.a3 - pRotMatrix.c1) / s; - z = (pRotMatrix.b1 - pRotMatrix.a2) / s; - w = static_cast<TReal>(0.25) * s; - } // else we have to check several cases - else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 ) - { - // Column 0: - TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * static_cast<TReal>(2.0); - x = static_cast<TReal>(0.25) * s; - y = (pRotMatrix.b1 + pRotMatrix.a2) / s; - z = (pRotMatrix.a3 + pRotMatrix.c1) / s; - w = (pRotMatrix.c2 - pRotMatrix.b3) / s; - } - else if( pRotMatrix.b2 > pRotMatrix.c3) - { - // Column 1: - TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * static_cast<TReal>(2.0); - x = (pRotMatrix.b1 + pRotMatrix.a2) / s; - y = static_cast<TReal>(0.25) * s; - z = (pRotMatrix.c2 + pRotMatrix.b3) / s; - w = (pRotMatrix.a3 - pRotMatrix.c1) / s; - } else - { - // Column 2: - TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * static_cast<TReal>(2.0); - x = (pRotMatrix.a3 + pRotMatrix.c1) / s; - y = (pRotMatrix.c2 + pRotMatrix.b3) / s; - z = static_cast<TReal>(0.25) * s; - w = (pRotMatrix.b1 - pRotMatrix.a2) / s; - } -} - -// --------------------------------------------------------------------------- -// Construction from euler angles -template<typename TReal> -inline aiQuaterniont<TReal>::aiQuaterniont( TReal fPitch, TReal fYaw, TReal fRoll ) -{ - const TReal fSinPitch(std::sin(fPitch*static_cast<TReal>(0.5))); - const TReal fCosPitch(std::cos(fPitch*static_cast<TReal>(0.5))); - const TReal fSinYaw(std::sin(fYaw*static_cast<TReal>(0.5))); - const TReal fCosYaw(std::cos(fYaw*static_cast<TReal>(0.5))); - const TReal fSinRoll(std::sin(fRoll*static_cast<TReal>(0.5))); - const TReal fCosRoll(std::cos(fRoll*static_cast<TReal>(0.5))); - const TReal fCosPitchCosYaw(fCosPitch*fCosYaw); - const TReal fSinPitchSinYaw(fSinPitch*fSinYaw); - x = fSinRoll * fCosPitchCosYaw - fCosRoll * fSinPitchSinYaw; - y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw; - z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw; - w = fCosRoll * fCosPitchCosYaw + fSinRoll * fSinPitchSinYaw; -} - -// --------------------------------------------------------------------------- -// Returns a matrix representation of the quaternion -template<typename TReal> -inline aiMatrix3x3t<TReal> aiQuaterniont<TReal>::GetMatrix() const -{ - aiMatrix3x3t<TReal> resMatrix; - resMatrix.a1 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (y * y + z * z); - resMatrix.a2 = static_cast<TReal>(2.0) * (x * y - z * w); - resMatrix.a3 = static_cast<TReal>(2.0) * (x * z + y * w); - resMatrix.b1 = static_cast<TReal>(2.0) * (x * y + z * w); - resMatrix.b2 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + z * z); - resMatrix.b3 = static_cast<TReal>(2.0) * (y * z - x * w); - resMatrix.c1 = static_cast<TReal>(2.0) * (x * z - y * w); - resMatrix.c2 = static_cast<TReal>(2.0) * (y * z + x * w); - resMatrix.c3 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + y * y); - - return resMatrix; -} - -// --------------------------------------------------------------------------- -// Construction from an axis-angle pair -template<typename TReal> -inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> axis, TReal angle) -{ - axis.Normalize(); - - const TReal sin_a = std::sin( angle / 2 ); - const TReal cos_a = std::cos( angle / 2 ); - x = axis.x * sin_a; - y = axis.y * sin_a; - z = axis.z * sin_a; - w = cos_a; -} -// --------------------------------------------------------------------------- -// Construction from am existing, normalized quaternion -template<typename TReal> -inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> normalized) -{ - x = normalized.x; - y = normalized.y; - z = normalized.z; - - const TReal t = static_cast<TReal>(1.0) - (x*x) - (y*y) - (z*z); - - if (t < static_cast<TReal>(0.0)) { - w = static_cast<TReal>(0.0); - } - else w = std::sqrt (t); -} - -// --------------------------------------------------------------------------- -// Performs a spherical interpolation between two quaternions -// Implementation adopted from the gmtl project. All others I found on the net fail in some cases. -// Congrats, gmtl! -template<typename TReal> -inline void aiQuaterniont<TReal>::Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, const aiQuaterniont& pEnd, TReal pFactor) -{ - // calc cosine theta - TReal cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w; - - // adjust signs (if necessary) - aiQuaterniont end = pEnd; - if( cosom < static_cast<TReal>(0.0)) - { - cosom = -cosom; - end.x = -end.x; // Reverse all signs - end.y = -end.y; - end.z = -end.z; - end.w = -end.w; - } - - // Calculate coefficients - TReal sclp, sclq; - if( (static_cast<TReal>(1.0) - cosom) > static_cast<TReal>(0.0001)) // 0.0001 -> some epsillon - { - // Standard case (slerp) - TReal omega, sinom; - omega = std::acos( cosom); // extract theta from dot product's cos theta - sinom = std::sin( omega); - sclp = std::sin( (static_cast<TReal>(1.0) - pFactor) * omega) / sinom; - sclq = std::sin( pFactor * omega) / sinom; - } else - { - // Very close, do linear interp (because it's faster) - sclp = static_cast<TReal>(1.0) - pFactor; - sclq = pFactor; - } - - pOut.x = sclp * pStart.x + sclq * end.x; - pOut.y = sclp * pStart.y + sclq * end.y; - pOut.z = sclp * pStart.z + sclq * end.z; - pOut.w = sclp * pStart.w + sclq * end.w; -} - -// --------------------------------------------------------------------------- -template<typename TReal> -inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Normalize() -{ - // compute the magnitude and divide through it - const TReal mag = std::sqrt(x*x + y*y + z*z + w*w); - if (mag) - { - const TReal invMag = static_cast<TReal>(1.0)/mag; - x *= invMag; - y *= invMag; - z *= invMag; - w *= invMag; - } - return *this; -} - -// --------------------------------------------------------------------------- -template<typename TReal> -inline aiQuaterniont<TReal> aiQuaterniont<TReal>::operator* (const aiQuaterniont& t) const -{ - return aiQuaterniont(w*t.w - x*t.x - y*t.y - z*t.z, - w*t.x + x*t.w + y*t.z - z*t.y, - w*t.y + y*t.w + z*t.x - x*t.z, - w*t.z + z*t.w + x*t.y - y*t.x); -} - -// --------------------------------------------------------------------------- -template<typename TReal> -inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Conjugate () -{ - x = -x; - y = -y; - z = -z; - return *this; -} - -// --------------------------------------------------------------------------- -template<typename TReal> -inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v) -{ - aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q; - qinv.Conjugate(); - - q = q*q2*qinv; - return aiVector3t<TReal>(q.x,q.y,q.z); -} - -#endif -#endif // AI_QUATERNION_INL_INC diff --git a/thirdparty/assimp/include/assimp/scene.h b/thirdparty/assimp/include/assimp/scene.h deleted file mode 100644 index b76709eb15..0000000000 --- a/thirdparty/assimp/include/assimp/scene.h +++ /dev/null @@ -1,429 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file scene.h - * @brief Defines the data structures in which the imported scene is returned. - */ -#pragma once -#ifndef AI_SCENE_H_INC -#define AI_SCENE_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> -#include <assimp/texture.h> -#include <assimp/mesh.h> -#include <assimp/light.h> -#include <assimp/camera.h> -#include <assimp/material.h> -#include <assimp/anim.h> -#include <assimp/metadata.h> - -#ifdef __cplusplus -# include <cstdlib> -extern "C" { -#endif - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wattributes" -#endif - -// ------------------------------------------------------------------------------- -/** - * A node in the imported hierarchy. - * - * Each node has name, a parent node (except for the root node), - * a transformation relative to its parent and possibly several child nodes. - * Simple file formats don't support hierarchical structures - for these formats - * the imported scene does consist of only a single root node without children. - */ -// ------------------------------------------------------------------------------- -struct ASSIMP_API aiNode -{ - /** The name of the node. - * - * The name might be empty (length of zero) but all nodes which - * need to be referenced by either bones or animations are named. - * Multiple nodes may have the same name, except for nodes which are referenced - * by bones (see #aiBone and #aiMesh::mBones). Their names *must* be unique. - * - * Cameras and lights reference a specific node by name - if there - * are multiple nodes with this name, they are assigned to each of them. - * <br> - * There are no limitations with regard to the characters contained in - * the name string as it is usually taken directly from the source file. - * - * Implementations should be able to handle tokens such as whitespace, tabs, - * line feeds, quotation marks, ampersands etc. - * - * Sometimes assimp introduces new nodes not present in the source file - * into the hierarchy (usually out of necessity because sometimes the - * source hierarchy format is simply not compatible). Their names are - * surrounded by @verbatim <> @endverbatim e.g. - * @verbatim<DummyRootNode> @endverbatim. - */ - C_STRUCT aiString mName; - - /** The transformation relative to the node's parent. */ - C_STRUCT aiMatrix4x4 mTransformation; - - /** Parent node. nullptr if this node is the root node. */ - C_STRUCT aiNode* mParent; - - /** The number of child nodes of this node. */ - unsigned int mNumChildren; - - /** The child nodes of this node. nullptr if mNumChildren is 0. */ - C_STRUCT aiNode** mChildren; - - /** The number of meshes of this node. */ - unsigned int mNumMeshes; - - /** The meshes of this node. Each entry is an index into the - * mesh list of the #aiScene. - */ - unsigned int* mMeshes; - - /** Metadata associated with this node or nullptr if there is no metadata. - * Whether any metadata is generated depends on the source file format. See the - * @link importer_notes @endlink page for more information on every source file - * format. Importers that don't document any metadata don't write any. - */ - C_STRUCT aiMetadata* mMetaData; - -#ifdef __cplusplus - /** Constructor */ - aiNode(); - - /** Construction from a specific name */ - explicit aiNode(const std::string& name); - - /** Destructor */ - ~aiNode(); - - /** Searches for a node with a specific name, beginning at this - * nodes. Normally you will call this method on the root node - * of the scene. - * - * @param name Name to search for - * @return nullptr or a valid Node if the search was successful. - */ - inline - const aiNode* FindNode(const aiString& name) const { - return FindNode(name.data); - } - - inline - aiNode* FindNode(const aiString& name) { - return FindNode(name.data); - } - - const aiNode* FindNode(const char* name) const; - - aiNode* FindNode(const char* name); - - /** - * @brief Will add new children. - * @param numChildren Number of children to add. - * @param children The array with pointers showing to the children. - */ - void addChildren(unsigned int numChildren, aiNode **children); -#endif // __cplusplus -}; - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -// ------------------------------------------------------------------------------- -/** - * Specifies that the scene data structure that was imported is not complete. - * This flag bypasses some internal validations and allows the import - * of animation skeletons, material libraries or camera animation paths - * using Assimp. Most applications won't support such data. - */ -#define AI_SCENE_FLAGS_INCOMPLETE 0x1 - -/** - * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS) - * if the validation is successful. In a validated scene you can be sure that - * any cross references in the data structure (e.g. vertex indices) are valid. - */ -#define AI_SCENE_FLAGS_VALIDATED 0x2 - -/** - * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS) - * if the validation is successful but some issues have been found. - * This can for example mean that a texture that does not exist is referenced - * by a material or that the bone weights for a vertex don't sum to 1.0 ... . - * In most cases you should still be able to use the import. This flag could - * be useful for applications which don't capture Assimp's log output. - */ -#define AI_SCENE_FLAGS_VALIDATION_WARNING 0x4 - -/** - * This flag is currently only set by the aiProcess_JoinIdenticalVertices step. - * It indicates that the vertices of the output meshes aren't in the internal - * verbose format anymore. In the verbose format all vertices are unique, - * no vertex is ever referenced by more than one face. - */ -#define AI_SCENE_FLAGS_NON_VERBOSE_FORMAT 0x8 - - /** - * Denotes pure height-map terrain data. Pure terrains usually consist of quads, - * sometimes triangles, in a regular grid. The x,y coordinates of all vertex - * positions refer to the x,y coordinates on the terrain height map, the z-axis - * stores the elevation at a specific point. - * - * TER (Terragen) and HMP (3D Game Studio) are height map formats. - * @note Assimp is probably not the best choice for loading *huge* terrains - - * fully triangulated data takes extremely much free store and should be avoided - * as long as possible (typically you'll do the triangulation when you actually - * need to render it). - */ -#define AI_SCENE_FLAGS_TERRAIN 0x10 - - /** - * Specifies that the scene data can be shared between structures. For example: - * one vertex in few faces. \ref AI_SCENE_FLAGS_NON_VERBOSE_FORMAT can not be - * used for this because \ref AI_SCENE_FLAGS_NON_VERBOSE_FORMAT has internal - * meaning about postprocessing steps. - */ -#define AI_SCENE_FLAGS_ALLOW_SHARED 0x20 - -// ------------------------------------------------------------------------------- -/** The root structure of the imported data. - * - * Everything that was imported from the given file can be accessed from here. - * Objects of this class are generally maintained and owned by Assimp, not - * by the caller. You shouldn't want to instance it, nor should you ever try to - * delete a given scene on your own. - */ -// ------------------------------------------------------------------------------- -struct aiScene -{ - /** Any combination of the AI_SCENE_FLAGS_XXX flags. By default - * this value is 0, no flags are set. Most applications will - * want to reject all scenes with the AI_SCENE_FLAGS_INCOMPLETE - * bit set. - */ - unsigned int mFlags; - - /** The root node of the hierarchy. - * - * There will always be at least the root node if the import - * was successful (and no special flags have been set). - * Presence of further nodes depends on the format and content - * of the imported file. - */ - C_STRUCT aiNode* mRootNode; - - /** The number of meshes in the scene. */ - unsigned int mNumMeshes; - - /** The array of meshes. - * - * Use the indices given in the aiNode structure to access - * this array. The array is mNumMeshes in size. If the - * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always - * be at least ONE material. - */ - C_STRUCT aiMesh** mMeshes; - - /** The number of materials in the scene. */ - unsigned int mNumMaterials; - - /** The array of materials. - * - * Use the index given in each aiMesh structure to access this - * array. The array is mNumMaterials in size. If the - * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always - * be at least ONE material. - */ - C_STRUCT aiMaterial** mMaterials; - - /** The number of animations in the scene. */ - unsigned int mNumAnimations; - - /** The array of animations. - * - * All animations imported from the given file are listed here. - * The array is mNumAnimations in size. - */ - C_STRUCT aiAnimation** mAnimations; - - /** The number of textures embedded into the file */ - unsigned int mNumTextures; - - /** The array of embedded textures. - * - * Not many file formats embed their textures into the file. - * An example is Quake's MDL format (which is also used by - * some GameStudio versions) - */ - C_STRUCT aiTexture** mTextures; - - /** The number of light sources in the scene. Light sources - * are fully optional, in most cases this attribute will be 0 - */ - unsigned int mNumLights; - - /** The array of light sources. - * - * All light sources imported from the given file are - * listed here. The array is mNumLights in size. - */ - C_STRUCT aiLight** mLights; - - /** The number of cameras in the scene. Cameras - * are fully optional, in most cases this attribute will be 0 - */ - unsigned int mNumCameras; - - /** The array of cameras. - * - * All cameras imported from the given file are listed here. - * The array is mNumCameras in size. The first camera in the - * array (if existing) is the default camera view into - * the scene. - */ - C_STRUCT aiCamera** mCameras; - - /** - * @brief The global metadata assigned to the scene itself. - * - * This data contains global metadata which belongs to the scene like - * unit-conversions, versions, vendors or other model-specific data. This - * can be used to store format-specific metadata as well. - */ - C_STRUCT aiMetadata* mMetaData; - - -#ifdef __cplusplus - - //! Default constructor - set everything to 0/nullptr - ASSIMP_API aiScene(); - - //! Destructor - ASSIMP_API ~aiScene(); - - //! Check whether the scene contains meshes - //! Unless no special scene flags are set this will always be true. - inline bool HasMeshes() const { - return mMeshes != nullptr && mNumMeshes > 0; - } - - //! Check whether the scene contains materials - //! Unless no special scene flags are set this will always be true. - inline bool HasMaterials() const { - return mMaterials != nullptr && mNumMaterials > 0; - } - - //! Check whether the scene contains lights - inline bool HasLights() const { - return mLights != nullptr && mNumLights > 0; - } - - //! Check whether the scene contains textures - inline bool HasTextures() const { - return mTextures != nullptr && mNumTextures > 0; - } - - //! Check whether the scene contains cameras - inline bool HasCameras() const { - return mCameras != nullptr && mNumCameras > 0; - } - - //! Check whether the scene contains animations - inline bool HasAnimations() const { - return mAnimations != nullptr && mNumAnimations > 0; - } - - //! Returns a short filename from a full path - static const char* GetShortFilename(const char* filename) { - const char* lastSlash = strrchr(filename, '/'); - if (lastSlash == nullptr) { - lastSlash = strrchr(filename, '\\'); - } - const char* shortFilename = lastSlash != nullptr ? lastSlash + 1 : filename; - return shortFilename; - } - - //! Returns an embedded texture - const aiTexture* GetEmbeddedTexture(const char* filename) const { - // lookup using texture ID (if referenced like: "*1", "*2", etc.) - if ('*' == *filename) { - int index = std::atoi(filename + 1); - if (0 > index || mNumTextures <= static_cast<unsigned>(index)) - return nullptr; - return mTextures[index]; - } - // lookup using filename - const char* shortFilename = GetShortFilename(filename); - for (unsigned int i = 0; i < mNumTextures; i++) { - const char* shortTextureFilename = GetShortFilename(mTextures[i]->mFilename.C_Str()); - if (strcmp(shortTextureFilename, shortFilename) == 0) { - return mTextures[i]; - } - } - return nullptr; - } -#endif // __cplusplus - - /** Internal data, do not touch */ -#ifdef __cplusplus - void* mPrivate; -#else - char* mPrivate; -#endif - -}; - -#ifdef __cplusplus -} //! namespace Assimp -#endif - -#endif // AI_SCENE_H_INC diff --git a/thirdparty/assimp/include/assimp/texture.h b/thirdparty/assimp/include/assimp/texture.h deleted file mode 100644 index 0867659f46..0000000000 --- a/thirdparty/assimp/include/assimp/texture.h +++ /dev/null @@ -1,226 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file texture.h - * @brief Defines texture helper structures for the library - * - * Used for file formats which embed their textures into the model file. - * Supported are both normal textures, which are stored as uncompressed - * pixels, and "compressed" textures, which are stored in a file format - * such as PNG or TGA. - */ -#pragma once -#ifndef AI_TEXTURE_H_INC -#define AI_TEXTURE_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#include <assimp/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// -------------------------------------------------------------------------------- - -/** \def AI_EMBEDDED_TEXNAME_PREFIX - * \ref AI_MAKE_EMBEDDED_TEXNAME - */ -#ifndef AI_EMBEDDED_TEXNAME_PREFIX -# define AI_EMBEDDED_TEXNAME_PREFIX "*" -#endif - -/** @def AI_MAKE_EMBEDDED_TEXNAME - * Used to build the reserved path name used by the material system to - * reference textures that are embedded into their corresponding - * model files. The parameter specifies the index of the texture - * (zero-based, in the aiScene::mTextures array) - */ -#if (!defined AI_MAKE_EMBEDDED_TEXNAME) -# define AI_MAKE_EMBEDDED_TEXNAME(_n_) AI_EMBEDDED_TEXNAME_PREFIX # _n_ -#endif - -#include "./Compiler/pushpack1.h" - -// -------------------------------------------------------------------------------- -/** @brief Helper structure to represent a texel in a ARGB8888 format -* -* Used by aiTexture. -*/ -struct aiTexel { - unsigned char b,g,r,a; - -#ifdef __cplusplus - //! Comparison operator - bool operator== (const aiTexel& other) const - { - return b == other.b && r == other.r && - g == other.g && a == other.a; - } - - //! Inverse comparison operator - bool operator!= (const aiTexel& other) const - { - return b != other.b || r != other.r || - g != other.g || a != other.a; - } - - //! Conversion to a floating-point 4d color - operator aiColor4D() const - { - return aiColor4D(r/255.f,g/255.f,b/255.f,a/255.f); - } -#endif // __cplusplus - -} PACK_STRUCT; - -#include "./Compiler/poppack1.h" - -#define HINTMAXTEXTURELEN 9 - -// -------------------------------------------------------------------------------- -/** Helper structure to describe an embedded texture - * - * Normally textures are contained in external files but some file formats embed - * them directly in the model file. There are two types of embedded textures: - * 1. Uncompressed textures. The color data is given in an uncompressed format. - * 2. Compressed textures stored in a file format like png or jpg. The raw file - * bytes are given so the application must utilize an image decoder (e.g. DevIL) to - * get access to the actual color data. - * - * Embedded textures are referenced from materials using strings like "*0", "*1", etc. - * as the texture paths (a single asterisk character followed by the - * zero-based index of the texture in the aiScene::mTextures array). - */ -struct aiTexture { - /** Width of the texture, in pixels - * - * If mHeight is zero the texture is compressed in a format - * like JPEG. In this case mWidth specifies the size of the - * memory area pcData is pointing to, in bytes. - */ - unsigned int mWidth; - - /** Height of the texture, in pixels - * - * If this value is zero, pcData points to an compressed texture - * in any format (e.g. JPEG). - */ - unsigned int mHeight; - - /** A hint from the loader to make it easier for applications - * to determine the type of embedded textures. - * - * If mHeight != 0 this member is show how data is packed. Hint will consist of - * two parts: channel order and channel bitness (count of the bits for every - * color channel). For simple parsing by the viewer it's better to not omit - * absent color channel and just use 0 for bitness. For example: - * 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888"; - * 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888"; - * 3. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel, achFormatHint == "rgba5650"; - * 4. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010"; - * If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional - * information about the texture file format used OR the - * file extension of the format without a trailing dot. If there - * are multiple file extensions for a format, the shortest - * extension is chosen (JPEG maps to 'jpg', not to 'jpeg'). - * E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case. - * The fourth character will always be '\\0'. - */ - char achFormatHint[ HINTMAXTEXTURELEN ];// 8 for string + 1 for terminator. - - /** Data of the texture. - * - * Points to an array of mWidth * mHeight aiTexel's. - * The format of the texture data is always ARGB8888 to - * make the implementation for user of the library as easy - * as possible. If mHeight = 0 this is a pointer to a memory - * buffer of size mWidth containing the compressed texture - * data. Good luck, have fun! - */ - C_STRUCT aiTexel* pcData; - - /** Texture original filename - * - * Used to get the texture reference - */ - C_STRUCT aiString mFilename; - -#ifdef __cplusplus - - //! For compressed textures (mHeight == 0): compare the - //! format hint against a given string. - //! @param s Input string. 3 characters are maximally processed. - //! Example values: "jpg", "png" - //! @return true if the given string matches the format hint - bool CheckFormat(const char* s) const { - if (nullptr == s) { - return false; - } - - return (0 == ::strncmp(achFormatHint, s, sizeof(achFormatHint))); - } - - // Construction - aiTexture() AI_NO_EXCEPT - : mWidth(0) - , mHeight(0) - , pcData(nullptr) - , mFilename() { - achFormatHint[0] = achFormatHint[1] = 0; - achFormatHint[2] = achFormatHint[3] = 0; - } - - // Destruction - ~aiTexture () { - delete[] pcData; - } -#endif -}; - - -#ifdef __cplusplus -} -#endif - -#endif // AI_TEXTURE_H_INC diff --git a/thirdparty/assimp/include/assimp/types.h b/thirdparty/assimp/include/assimp/types.h deleted file mode 100644 index e32cae331c..0000000000 --- a/thirdparty/assimp/include/assimp/types.h +++ /dev/null @@ -1,544 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file types.h - * Basic data types and primitives, such as vectors or colors. - */ -#pragma once -#ifndef AI_TYPES_H_INC -#define AI_TYPES_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -// Some runtime headers -#include <sys/types.h> -#include <stddef.h> -#include <string.h> -#include <limits.h> -#include <stdint.h> - -// Our compile configuration -#include <assimp/defs.h> - -// Some types moved to separate header due to size of operators -#include <assimp/vector3.h> -#include <assimp/vector2.h> -#include <assimp/color4.h> -#include <assimp/matrix3x3.h> -#include <assimp/matrix4x4.h> -#include <assimp/quaternion.h> - -typedef int32_t ai_int32; -typedef uint32_t ai_uint32 ; - -#ifdef __cplusplus -#include <cstring> -#include <new> // for std::nothrow_t -#include <string> // for aiString::Set(const std::string&) - -namespace Assimp { -//! @cond never -namespace Intern { - // -------------------------------------------------------------------- - /** @brief Internal helper class to utilize our internal new/delete - * routines for allocating object of this and derived classes. - * - * By doing this you can safely share class objects between Assimp - * and the application - it works even over DLL boundaries. A good - * example is the #IOSystem where the application allocates its custom - * #IOSystem, then calls #Importer::SetIOSystem(). When the Importer - * destructs, Assimp calls operator delete on the stored #IOSystem. - * If it lies on a different heap than Assimp is working with, - * the application is determined to crash. - */ - // -------------------------------------------------------------------- -#ifndef SWIG - struct ASSIMP_API AllocateFromAssimpHeap { - // http://www.gotw.ca/publications/mill15.htm - - // new/delete overload - void *operator new ( size_t num_bytes) /* throw( std::bad_alloc ) */; - void *operator new ( size_t num_bytes, const std::nothrow_t& ) throw(); - void operator delete ( void* data); - - // array new/delete overload - void *operator new[] ( size_t num_bytes) /* throw( std::bad_alloc ) */; - void *operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw(); - void operator delete[] ( void* data); - - }; // struct AllocateFromAssimpHeap -#endif -} // namespace Intern - //! @endcond -} // namespace Assimp - -extern "C" { -#endif - -/** Maximum dimension for strings, ASSIMP strings are zero terminated. */ -#ifdef __cplusplus - static const size_t MAXLEN = 1024; -#else -# define MAXLEN 1024 -#endif - -// ---------------------------------------------------------------------------------- -/** Represents a plane in a three-dimensional, euclidean space -*/ -struct aiPlane { -#ifdef __cplusplus - aiPlane () AI_NO_EXCEPT : a(0.f), b(0.f), c(0.f), d(0.f) {} - aiPlane (ai_real _a, ai_real _b, ai_real _c, ai_real _d) - : a(_a), b(_b), c(_c), d(_d) {} - - aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {} - -#endif // !__cplusplus - - //! Plane equation - ai_real a,b,c,d; -}; // !struct aiPlane - -// ---------------------------------------------------------------------------------- -/** Represents a ray -*/ -struct aiRay { -#ifdef __cplusplus - aiRay () AI_NO_EXCEPT {} - aiRay (const aiVector3D& _pos, const aiVector3D& _dir) - : pos(_pos), dir(_dir) {} - - aiRay (const aiRay& o) : pos (o.pos), dir (o.dir) {} - -#endif // !__cplusplus - - //! Position and direction of the ray - C_STRUCT aiVector3D pos, dir; -}; // !struct aiRay - -// ---------------------------------------------------------------------------------- -/** Represents a color in Red-Green-Blue space. -*/ -struct aiColor3D -{ -#ifdef __cplusplus - aiColor3D () AI_NO_EXCEPT : r(0.0f), g(0.0f), b(0.0f) {} - aiColor3D (ai_real _r, ai_real _g, ai_real _b) : r(_r), g(_g), b(_b) {} - explicit aiColor3D (ai_real _r) : r(_r), g(_r), b(_r) {} - aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {} - - aiColor3D &operator=(const aiColor3D &o) { - r = o.r; - g = o.g; - b = o.b; - return *this; - } - - /** Component-wise comparison */ - // TODO: add epsilon? - bool operator == (const aiColor3D& other) const - {return r == other.r && g == other.g && b == other.b;} - - /** Component-wise inverse comparison */ - // TODO: add epsilon? - bool operator != (const aiColor3D& other) const - {return r != other.r || g != other.g || b != other.b;} - - /** Component-wise comparison */ - // TODO: add epsilon? - bool operator < (const aiColor3D& other) const { - return r < other.r || ( r == other.r && (g < other.g || (g == other.g && b < other.b ) ) ); - } - - /** Component-wise addition */ - aiColor3D operator+(const aiColor3D& c) const { - return aiColor3D(r+c.r,g+c.g,b+c.b); - } - - /** Component-wise subtraction */ - aiColor3D operator-(const aiColor3D& c) const { - return aiColor3D(r-c.r,g-c.g,b-c.b); - } - - /** Component-wise multiplication */ - aiColor3D operator*(const aiColor3D& c) const { - return aiColor3D(r*c.r,g*c.g,b*c.b); - } - - /** Multiply with a scalar */ - aiColor3D operator*(ai_real f) const { - return aiColor3D(r*f,g*f,b*f); - } - - /** Access a specific color component */ - ai_real operator[](unsigned int i) const { - return *(&r + i); - } - - /** Access a specific color component */ - ai_real& operator[](unsigned int i) { - if ( 0 == i ) { - return r; - } else if ( 1 == i ) { - return g; - } else if ( 2 == i ) { - return b; - } - return r; - } - - /** Check whether a color is black */ - bool IsBlack() const { - static const ai_real epsilon = ai_real(10e-3); - return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon; - } - -#endif // !__cplusplus - - //! Red, green and blue color values - ai_real r, g, b; -}; // !struct aiColor3D - -// ---------------------------------------------------------------------------------- -/** Represents an UTF-8 string, zero byte terminated. - * - * The character set of an aiString is explicitly defined to be UTF-8. This Unicode - * transformation was chosen in the belief that most strings in 3d files are limited - * to ASCII, thus the character set needed to be strictly ASCII compatible. - * - * Most text file loaders provide proper Unicode input file handling, special unicode - * characters are correctly transcoded to UTF8 and are kept throughout the libraries' - * import pipeline. - * - * For most applications, it will be absolutely sufficient to interpret the - * aiString as ASCII data and work with it as one would work with a plain char*. - * Windows users in need of proper support for i.e asian characters can use the - * MultiByteToWideChar(), WideCharToMultiByte() WinAPI functionality to convert the - * UTF-8 strings to their working character set (i.e. MBCS, WideChar). - * - * We use this representation instead of std::string to be C-compatible. The - * (binary) length of such a string is limited to MAXLEN characters (including the - * the terminating zero). -*/ -struct aiString -{ -#ifdef __cplusplus - /** Default constructor, the string is set to have zero length */ - aiString() AI_NO_EXCEPT - : length( 0 ) { - data[0] = '\0'; - -#ifdef ASSIMP_BUILD_DEBUG - // Debug build: overwrite the string on its full length with ESC (27) - memset(data+1,27,MAXLEN-1); -#endif - } - - /** Copy constructor */ - aiString(const aiString& rOther) - : length(rOther.length) - { - // Crop the string to the maximum length - length = length>=MAXLEN?MAXLEN-1:length; - memcpy( data, rOther.data, length); - data[length] = '\0'; - } - - /** Constructor from std::string */ - explicit aiString(const std::string& pString) : - length( (ai_uint32) pString.length()) - { - length = length>=MAXLEN?MAXLEN-1:length; - memcpy( data, pString.c_str(), length); - data[length] = '\0'; - } - - /** Copy a std::string to the aiString */ - void Set( const std::string& pString) { - if( pString.length() > MAXLEN - 1) { - return; - } - length = (ai_uint32)pString.length(); - memcpy( data, pString.c_str(), length); - data[length] = 0; - } - - /** Copy a const char* to the aiString */ - void Set( const char* sz) { - const ai_int32 len = (ai_uint32) ::strlen(sz); - if( len > (ai_int32)MAXLEN - 1) { - return; - } - length = len; - memcpy( data, sz, len); - data[len] = 0; - } - - - /** Assignment operator */ - aiString& operator = (const aiString &rOther) { - if (this == &rOther) { - return *this; - } - - length = rOther.length;; - memcpy( data, rOther.data, length); - data[length] = '\0'; - return *this; - } - - - /** Assign a const char* to the string */ - aiString& operator = (const char* sz) { - Set(sz); - return *this; - } - - /** Assign a cstd::string to the string */ - aiString& operator = ( const std::string& pString) { - Set(pString); - return *this; - } - - /** Comparison operator */ - bool operator==(const aiString& other) const { - return (length == other.length && 0 == memcmp(data,other.data,length)); - } - - /** Inverse comparison operator */ - bool operator!=(const aiString& other) const { - return (length != other.length || 0 != memcmp(data,other.data,length)); - } - - /** Append a string to the string */ - void Append (const char* app) { - const ai_uint32 len = (ai_uint32) ::strlen(app); - if (!len) { - return; - } - if (length + len >= MAXLEN) { - return; - } - - memcpy(&data[length],app,len+1); - length += len; - } - - /** Clear the string - reset its length to zero */ - void Clear () { - length = 0; - data[0] = '\0'; - -#ifdef ASSIMP_BUILD_DEBUG - // Debug build: overwrite the string on its full length with ESC (27) - memset(data+1,27,MAXLEN-1); -#endif - } - - /** Returns a pointer to the underlying zero-terminated array of characters */ - const char* C_Str() const { - return data; - } - -#endif // !__cplusplus - - /** Binary length of the string excluding the terminal 0. This is NOT the - * logical length of strings containing UTF-8 multi-byte sequences! It's - * the number of bytes from the beginning of the string to its end.*/ - ai_uint32 length; - - /** String buffer. Size limit is MAXLEN */ - char data[MAXLEN]; -} ; // !struct aiString - - -// ---------------------------------------------------------------------------------- -/** Standard return type for some library functions. - * Rarely used, and if, mostly in the C API. - */ -typedef enum aiReturn -{ - /** Indicates that a function was successful */ - aiReturn_SUCCESS = 0x0, - - /** Indicates that a function failed */ - aiReturn_FAILURE = -0x1, - - /** Indicates that not enough memory was available - * to perform the requested operation - */ - aiReturn_OUTOFMEMORY = -0x3, - - /** @cond never - * Force 32-bit size enum - */ - _AI_ENFORCE_ENUM_SIZE = 0x7fffffff - - /// @endcond -} aiReturn; // !enum aiReturn - -// just for backwards compatibility, don't use these constants anymore -#define AI_SUCCESS aiReturn_SUCCESS -#define AI_FAILURE aiReturn_FAILURE -#define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY - -// ---------------------------------------------------------------------------------- -/** Seek origins (for the virtual file system API). - * Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END. - */ -enum aiOrigin -{ - /** Beginning of the file */ - aiOrigin_SET = 0x0, - - /** Current position of the file pointer */ - aiOrigin_CUR = 0x1, - - /** End of the file, offsets must be negative */ - aiOrigin_END = 0x2, - - /** @cond never - * Force 32-bit size enum - */ - _AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff - - /// @endcond -}; // !enum aiOrigin - -// ---------------------------------------------------------------------------------- -/** @brief Enumerates predefined log streaming destinations. - * Logging to these streams can be enabled with a single call to - * #LogStream::createDefaultStream. - */ -enum aiDefaultLogStream -{ - /** Stream the log to a file */ - aiDefaultLogStream_FILE = 0x1, - - /** Stream the log to std::cout */ - aiDefaultLogStream_STDOUT = 0x2, - - /** Stream the log to std::cerr */ - aiDefaultLogStream_STDERR = 0x4, - - /** MSVC only: Stream the log the the debugger - * (this relies on OutputDebugString from the Win32 SDK) - */ - aiDefaultLogStream_DEBUGGER = 0x8, - - /** @cond never - * Force 32-bit size enum - */ - _AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff - /// @endcond -}; // !enum aiDefaultLogStream - -// just for backwards compatibility, don't use these constants anymore -#define DLS_FILE aiDefaultLogStream_FILE -#define DLS_STDOUT aiDefaultLogStream_STDOUT -#define DLS_STDERR aiDefaultLogStream_STDERR -#define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER - -// ---------------------------------------------------------------------------------- -/** Stores the memory requirements for different components (e.g. meshes, materials, - * animations) of an import. All sizes are in bytes. - * @see Importer::GetMemoryRequirements() -*/ -struct aiMemoryInfo -{ -#ifdef __cplusplus - - /** Default constructor */ - aiMemoryInfo() AI_NO_EXCEPT - : textures (0) - , materials (0) - , meshes (0) - , nodes (0) - , animations (0) - , cameras (0) - , lights (0) - , total (0) - {} - -#endif - - /** Storage allocated for texture data */ - unsigned int textures; - - /** Storage allocated for material data */ - unsigned int materials; - - /** Storage allocated for mesh data */ - unsigned int meshes; - - /** Storage allocated for node data */ - unsigned int nodes; - - /** Storage allocated for animation data */ - unsigned int animations; - - /** Storage allocated for camera data */ - unsigned int cameras; - - /** Storage allocated for light data */ - unsigned int lights; - - /** Total storage allocated for the full import. */ - unsigned int total; -}; // !struct aiMemoryInfo - -#ifdef __cplusplus -} -#endif //! __cplusplus - -// Include implementation files -#include "vector2.inl" -#include "vector3.inl" -#include "color4.inl" -#include "quaternion.inl" -#include "matrix3x3.inl" -#include "matrix4x4.inl" - -#endif // AI_TYPES_H_INC diff --git a/thirdparty/assimp/include/assimp/vector2.h b/thirdparty/assimp/include/assimp/vector2.h deleted file mode 100644 index c8b1ebbbc2..0000000000 --- a/thirdparty/assimp/include/assimp/vector2.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file vector2.h - * @brief 2D vector structure, including operators when compiling in C++ - */ -#pragma once -#ifndef AI_VECTOR2D_H_INC -#define AI_VECTOR2D_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -# include <cmath> -#else -# include <math.h> -#endif - -#include "defs.h" - -// ---------------------------------------------------------------------------------- -/** Represents a two-dimensional vector. - */ - -#ifdef __cplusplus -template <typename TReal> -class aiVector2t { -public: - aiVector2t () : x(), y() {} - aiVector2t (TReal _x, TReal _y) : x(_x), y(_y) {} - explicit aiVector2t (TReal _xyz) : x(_xyz), y(_xyz) {} - aiVector2t (const aiVector2t& o) = default; - - void Set( TReal pX, TReal pY); - TReal SquareLength() const ; - TReal Length() const ; - aiVector2t& Normalize(); - - const aiVector2t& operator += (const aiVector2t& o); - const aiVector2t& operator -= (const aiVector2t& o); - const aiVector2t& operator *= (TReal f); - const aiVector2t& operator /= (TReal f); - - TReal operator[](unsigned int i) const; - - bool operator== (const aiVector2t& other) const; - bool operator!= (const aiVector2t& other) const; - - bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const; - - aiVector2t& operator= (TReal f); - const aiVector2t SymMul(const aiVector2t& o); - - template <typename TOther> - operator aiVector2t<TOther> () const; - - TReal x, y; -}; - -typedef aiVector2t<ai_real> aiVector2D; - -#else - -struct aiVector2D { - ai_real x, y; -}; - -#endif // __cplusplus - -#endif // AI_VECTOR2D_H_INC diff --git a/thirdparty/assimp/include/assimp/vector2.inl b/thirdparty/assimp/include/assimp/vector2.inl deleted file mode 100644 index 4bbf432ff8..0000000000 --- a/thirdparty/assimp/include/assimp/vector2.inl +++ /dev/null @@ -1,248 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file vector2.inl - * @brief Inline implementation of aiVector2t<TReal> operators - */ -#pragma once -#ifndef AI_VECTOR2D_INL_INC -#define AI_VECTOR2D_INL_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -#include <assimp/vector2.h> - -#include <cmath> - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -template <typename TOther> -aiVector2t<TReal>::operator aiVector2t<TOther> () const { - return aiVector2t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y)); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -void aiVector2t<TReal>::Set( TReal pX, TReal pY) { - x = pX; y = pY; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -TReal aiVector2t<TReal>::SquareLength() const { - return x*x + y*y; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -TReal aiVector2t<TReal>::Length() const { - return std::sqrt( SquareLength()); -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -aiVector2t<TReal>& aiVector2t<TReal>::Normalize() { - *this /= Length(); - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -const aiVector2t<TReal>& aiVector2t<TReal>::operator += (const aiVector2t& o) { - x += o.x; y += o.y; - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -const aiVector2t<TReal>& aiVector2t<TReal>::operator -= (const aiVector2t& o) { - x -= o.x; y -= o.y; - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -const aiVector2t<TReal>& aiVector2t<TReal>::operator *= (TReal f) { - x *= f; y *= f; - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -const aiVector2t<TReal>& aiVector2t<TReal>::operator /= (TReal f) { - x /= f; y /= f; - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -TReal aiVector2t<TReal>::operator[](unsigned int i) const { - switch (i) { - case 0: - return x; - case 1: - return y; - default: - break; - - } - return x; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -bool aiVector2t<TReal>::operator== (const aiVector2t& other) const { - return x == other.x && y == other.y; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const { - return x != other.x || y != other.y; -} - -// --------------------------------------------------------------------------- -template<typename TReal> -inline -bool aiVector2t<TReal>::Equal(const aiVector2t& other, TReal epsilon) const { - return - std::abs(x - other.x) <= epsilon && - std::abs(y - other.y) <= epsilon; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f) { - x = y = f; - return *this; -} - -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -inline -const aiVector2t<TReal> aiVector2t<TReal>::SymMul(const aiVector2t& o) { - return aiVector2t(x*o.x,y*o.y); -} - - -// ------------------------------------------------------------------------------------------------ -// symmetric addition -template <typename TReal> -inline -aiVector2t<TReal> operator + (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2) { - return aiVector2t<TReal>( v1.x + v2.x, v1.y + v2.y); -} - -// ------------------------------------------------------------------------------------------------ -// symmetric subtraction -template <typename TReal> -inline -aiVector2t<TReal> operator - (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2) { - return aiVector2t<TReal>( v1.x - v2.x, v1.y - v2.y); -} - -// ------------------------------------------------------------------------------------------------ -// scalar product -template <typename TReal> -inline -TReal operator * (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2) { - return v1.x*v2.x + v1.y*v2.y; -} - -// ------------------------------------------------------------------------------------------------ -// scalar multiplication -template <typename TReal> -inline -aiVector2t<TReal> operator * ( TReal f, const aiVector2t<TReal>& v) { - return aiVector2t<TReal>( f*v.x, f*v.y); -} - -// ------------------------------------------------------------------------------------------------ -// and the other way around -template <typename TReal> -inline -aiVector2t<TReal> operator * ( const aiVector2t<TReal>& v, TReal f) { - return aiVector2t<TReal>( f*v.x, f*v.y); -} - -// ------------------------------------------------------------------------------------------------ -// scalar division -template <typename TReal> -inline -aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, TReal f) { - return v * (1/f); -} - -// ------------------------------------------------------------------------------------------------ -// vector division -template <typename TReal> -inline -aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, const aiVector2t<TReal>& v2) { - return aiVector2t<TReal>(v.x / v2.x,v.y / v2.y); -} - -// ------------------------------------------------------------------------------------------------ -// vector negation -template <typename TReal> -inline -aiVector2t<TReal> operator - ( const aiVector2t<TReal>& v) { - return aiVector2t<TReal>( -v.x, -v.y); -} - -#endif - -#endif // AI_VECTOR2D_INL_INC diff --git a/thirdparty/assimp/include/assimp/vector3.h b/thirdparty/assimp/include/assimp/vector3.h deleted file mode 100644 index fffeb12ad7..0000000000 --- a/thirdparty/assimp/include/assimp/vector3.h +++ /dev/null @@ -1,146 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ -/** @file vector3.h - * @brief 3D vector structure, including operators when compiling in C++ - */ -#pragma once -#ifndef AI_VECTOR3D_H_INC -#define AI_VECTOR3D_H_INC - -#ifdef __GNUC__ -# pragma GCC system_header -#endif - -#ifdef __cplusplus -# include <cmath> -#else -# include <math.h> -#endif - -#include <assimp/defs.h> - -#ifdef __cplusplus - -template<typename TReal> class aiMatrix3x3t; -template<typename TReal> class aiMatrix4x4t; - -// --------------------------------------------------------------------------- -/** Represents a three-dimensional vector. */ -template <typename TReal> -class aiVector3t { -public: - aiVector3t() AI_NO_EXCEPT : x(), y(), z() {} - aiVector3t(TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {} - explicit aiVector3t (TReal _xyz ) : x(_xyz), y(_xyz), z(_xyz) {} - aiVector3t( const aiVector3t& o ) = default; - - // combined operators - const aiVector3t& operator += (const aiVector3t& o); - const aiVector3t& operator -= (const aiVector3t& o); - const aiVector3t& operator *= (TReal f); - const aiVector3t& operator /= (TReal f); - - // transform vector by matrix - aiVector3t& operator *= (const aiMatrix3x3t<TReal>& mat); - aiVector3t& operator *= (const aiMatrix4x4t<TReal>& mat); - - // access a single element - TReal operator[](unsigned int i) const; - TReal& operator[](unsigned int i); - - // comparison - bool operator== (const aiVector3t& other) const; - bool operator!= (const aiVector3t& other) const; - bool operator < (const aiVector3t& other) const; - - bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const; - - template <typename TOther> - operator aiVector3t<TOther> () const; - - /** @brief Set the components of a vector - * @param pX X component - * @param pY Y component - * @param pZ Z component */ - void Set( TReal pX, TReal pY, TReal pZ); - - /** @brief Get the squared length of the vector - * @return Square length */ - TReal SquareLength() const; - - /** @brief Get the length of the vector - * @return length */ - TReal Length() const; - - - /** @brief Normalize the vector */ - aiVector3t& Normalize(); - - /** @brief Normalize the vector with extra check for zero vectors */ - aiVector3t& NormalizeSafe(); - - /** @brief Componentwise multiplication of two vectors - * - * Note that vec*vec yields the dot product. - * @param o Second factor */ - const aiVector3t SymMul(const aiVector3t& o); - - TReal x, y, z; -}; - - -typedef aiVector3t<ai_real> aiVector3D; - -#else - -struct aiVector3D { - ai_real x, y, z; -}; - -#endif // __cplusplus - -#ifdef __cplusplus - -#endif // __cplusplus - -#endif // AI_VECTOR3D_H_INC diff --git a/thirdparty/assimp/include/assimp/vector3.inl b/thirdparty/assimp/include/assimp/vector3.inl deleted file mode 100644 index 6682d3b32c..0000000000 --- a/thirdparty/assimp/include/assimp/vector3.inl +++ /dev/null @@ -1,309 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file vector3.inl - * @brief Inline implementation of aiVector3t<TReal> operators - */ -#pragma once -#ifndef AI_VECTOR3D_INL_INC -#define AI_VECTOR3D_INL_INC - -#ifdef __cplusplus -#include <assimp/vector3.h> - -#include <cmath> - -// ------------------------------------------------------------------------------------------------ -/** Transformation of a vector by a 3x3 matrix */ -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator * (const aiMatrix3x3t<TReal>& pMatrix, const aiVector3t<TReal>& pVector) { - aiVector3t<TReal> res; - res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z; - res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z; - res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z; - return res; -} - -// ------------------------------------------------------------------------------------------------ -/** Transformation of a vector by a 4x4 matrix */ -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator * (const aiMatrix4x4t<TReal>& pMatrix, const aiVector3t<TReal>& pVector) { - aiVector3t<TReal> res; - res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z + pMatrix.a4; - res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z + pMatrix.b4; - res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z + pMatrix.c4; - return res; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -template <typename TOther> -aiVector3t<TReal>::operator aiVector3t<TOther> () const { - return aiVector3t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y),static_cast<TOther>(z)); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -void aiVector3t<TReal>::Set( TReal pX, TReal pY, TReal pZ) { - x = pX; - y = pY; - z = pZ; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal aiVector3t<TReal>::SquareLength() const { - return x*x + y*y + z*z; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal aiVector3t<TReal>::Length() const { - return std::sqrt( SquareLength()); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal>& aiVector3t<TReal>::Normalize() { - *this /= Length(); - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal>& aiVector3t<TReal>::NormalizeSafe() { - TReal len = Length(); - if ( len > static_cast< TReal >( 0 ) ) { - *this /= len; - } - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiVector3t<TReal>& aiVector3t<TReal>::operator += (const aiVector3t<TReal>& o) { - x += o.x; - y += o.y; - z += o.z; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiVector3t<TReal>& aiVector3t<TReal>::operator -= (const aiVector3t<TReal>& o) { - x -= o.x; - y -= o.y; - z -= o.z; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiVector3t<TReal>& aiVector3t<TReal>::operator *= (TReal f) { - x *= f; - y *= f; - z *= f; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiVector3t<TReal>& aiVector3t<TReal>::operator /= (TReal f) { - const TReal invF = (TReal) 1.0 / f; - x *= invF; - y *= invF; - z *= invF; - - return *this; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& mat){ - return (*this = mat * (*this)); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix4x4t<TReal>& mat){ - return (*this = mat * (*this)); -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal aiVector3t<TReal>::operator[](unsigned int i) const { - switch (i) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - default: - break; - } - return x; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -TReal& aiVector3t<TReal>::operator[](unsigned int i) { -// return *(&x + i); - switch (i) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - default: - break; - } - return x; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiVector3t<TReal>::operator== (const aiVector3t<TReal>& other) const { - return x == other.x && y == other.y && z == other.z; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const { - return x != other.x || y != other.y || z != other.z; -} -// --------------------------------------------------------------------------- -template<typename TReal> -AI_FORCE_INLINE -bool aiVector3t<TReal>::Equal(const aiVector3t<TReal>& other, TReal epsilon) const { - return - std::abs(x - other.x) <= epsilon && - std::abs(y - other.y) <= epsilon && - std::abs(z - other.z) <= epsilon; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -bool aiVector3t<TReal>::operator < (const aiVector3t<TReal>& other) const { - return x != other.x ? x < other.x : y != other.y ? y < other.y : z < other.z; -} -// ------------------------------------------------------------------------------------------------ -template <typename TReal> -AI_FORCE_INLINE -const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) { - return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z); -} -// ------------------------------------------------------------------------------------------------ -// symmetric addition -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator + (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) { - return aiVector3t<TReal>( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); -} -// ------------------------------------------------------------------------------------------------ -// symmetric subtraction -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator - (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) { - return aiVector3t<TReal>( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); -} -// ------------------------------------------------------------------------------------------------ -// scalar product -template <typename TReal> -AI_FORCE_INLINE -TReal operator * (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) { - return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; -} -// ------------------------------------------------------------------------------------------------ -// scalar multiplication -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator * ( TReal f, const aiVector3t<TReal>& v) { - return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z); -} -// ------------------------------------------------------------------------------------------------ -// and the other way around -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator * ( const aiVector3t<TReal>& v, TReal f) { - return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z); -} -// ------------------------------------------------------------------------------------------------ -// scalar division -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, TReal f) { - return v * (1/f); -} -// ------------------------------------------------------------------------------------------------ -// vector division -template <typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, const aiVector3t<TReal>& v2) { - return aiVector3t<TReal>(v.x / v2.x,v.y / v2.y,v.z / v2.z); -} -// ------------------------------------------------------------------------------------------------ -// cross product -template<typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator ^ ( const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) { - return aiVector3t<TReal>( v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x); -} -// ------------------------------------------------------------------------------------------------ -// vector negation -template<typename TReal> -AI_FORCE_INLINE -aiVector3t<TReal> operator - ( const aiVector3t<TReal>& v) { - return aiVector3t<TReal>( -v.x, -v.y, -v.z); -} - -// ------------------------------------------------------------------------------------------------ - -#endif // __cplusplus -#endif // AI_VECTOR3D_INL_INC diff --git a/thirdparty/assimp/include/assimp/version.h b/thirdparty/assimp/include/assimp/version.h deleted file mode 100644 index 2fdd37a43c..0000000000 --- a/thirdparty/assimp/include/assimp/version.h +++ /dev/null @@ -1,115 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file version.h - * @brief Functions to query the version of the Assimp runtime, check - * compile flags, ... - */ -#pragma once -#ifndef AI_VERSION_H_INC -#define AI_VERSION_H_INC - -#include <assimp/defs.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------------- -/** @brief Returns a string with legal copyright and licensing information - * about Assimp. The string may include multiple lines. - * @return Pointer to static string. - */ -ASSIMP_API const char* aiGetLegalString (void); - -// --------------------------------------------------------------------------- -/** @brief Returns the current minor version number of Assimp. - * @return Minor version of the Assimp runtime the application was - * linked/built against - */ -ASSIMP_API unsigned int aiGetVersionMinor (void); - -// --------------------------------------------------------------------------- -/** @brief Returns the current major version number of Assimp. - * @return Major version of the Assimp runtime the application was - * linked/built against - */ -ASSIMP_API unsigned int aiGetVersionMajor (void); - -// --------------------------------------------------------------------------- -/** @brief Returns the repository revision of the Assimp runtime. - * @return SVN Repository revision number of the Assimp runtime the - * application was linked/built against. - */ -ASSIMP_API unsigned int aiGetVersionRevision (void); - -// --------------------------------------------------------------------------- -/** @brief Returns the branchname of the Assimp runtime. - * @return The current branch name. - */ -ASSIMP_API const char *aiGetBranchName(); - -//! Assimp was compiled as a shared object (Windows: DLL) -#define ASSIMP_CFLAGS_SHARED 0x1 -//! Assimp was compiled against STLport -#define ASSIMP_CFLAGS_STLPORT 0x2 -//! Assimp was compiled as a debug build -#define ASSIMP_CFLAGS_DEBUG 0x4 - -//! Assimp was compiled with ASSIMP_BUILD_BOOST_WORKAROUND defined -#define ASSIMP_CFLAGS_NOBOOST 0x8 -//! Assimp was compiled with ASSIMP_BUILD_SINGLETHREADED defined -#define ASSIMP_CFLAGS_SINGLETHREADED 0x10 - -// --------------------------------------------------------------------------- -/** @brief Returns assimp's compile flags - * @return Any bitwise combination of the ASSIMP_CFLAGS_xxx constants. - */ -ASSIMP_API unsigned int aiGetCompileFlags (void); - -#ifdef __cplusplus -} // end extern "C" -#endif - -#endif // !! #ifndef AI_VERSION_H_INC - diff --git a/thirdparty/assimp/revision.h b/thirdparty/assimp/revision.h deleted file mode 100644 index 66eb875303..0000000000 --- a/thirdparty/assimp/revision.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ASSIMP_REVISION_H_INC -#define ASSIMP_REVISION_H_INC - -#define GitVersion 0x308db73d -#define GitBranch "master" - -#define VER_MAJOR 5 -#define VER_MINOR 0 -#define VER_PATCH 0 -#define VER_BUILD 0 - -#define STR_HELP(x) #x -#define STR(x) STR_HELP(x) - -#define VER_FILEVERSION VER_MAJOR,VER_MINOR,VER_PATCH,VER_BUILD -#if (GitVersion == 0) -#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) -#else -#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit 308db73d)" -#endif - -#ifdef NDEBUG -#define VER_ORIGINAL_FILENAME_STR "assimp.dll" -#else -#define VER_ORIGINAL_FILENAME_STR "assimp.dll" -#endif // NDEBUG - -#endif // ASSIMP_REVISION_H_INC |