diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2019-11-06 12:55:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-06 12:55:45 +0100 |
commit | b30e6496bdc640422b5d708f27acb860a927425f (patch) | |
tree | d1eba0971b63f8f8e39e6f2752fc8d9944960318 | |
parent | 245c99175c242bdc60a212cc84986b1a9ad5aa08 (diff) | |
parent | 5fb160c7c692c469488f11aca90a36ac3248dfee (diff) |
Merge pull request #33347 from RevoluPowered/demo/assimp-importer-fbx
FBX Skinning and batch of fixes
114 files changed, 2717 insertions, 4551 deletions
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub index 275f1ff5e9..5e66b50de3 100644 --- a/modules/assimp/SCsub +++ b/modules/assimp/SCsub @@ -72,6 +72,9 @@ env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X3D_IMPORTER']) env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER']) env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF2_IMPORTER']) env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_M3D_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MMD_IMPORTER']) + if(env['platform'] == 'windows'): env_assimp.Append(CPPDEFINES=['PLATFORM_WINDOWS']) diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp index 1ea9399c02..830e6e7e0c 100644 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ b/modules/assimp/editor_scene_importer_assimp.cpp @@ -29,35 +29,42 @@ /*************************************************************************/ #include "editor_scene_importer_assimp.h" - -#include "core/bind/core_bind.h" #include "core/io/image_loader.h" -#include "editor/editor_file_system.h" -#include "editor/editor_settings.h" #include "editor/import/resource_importer_scene.h" #include "import_utils.h" #include "scene/3d/camera.h" #include "scene/3d/light.h" #include "scene/3d/mesh_instance.h" -#include "scene/animation/animation_player.h" #include "scene/main/node.h" #include "scene/resources/material.h" #include "scene/resources/surface_tool.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 <zutil.h> -#include <assimp/DefaultLogger.hpp> #include <assimp/Importer.hpp> #include <assimp/LogStream.hpp> -#include <assimp/Logger.hpp> #include <string> +// 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 NULL; +} + void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const { const String import_setting_string = "filesystem/import/open_asset_import/"; @@ -69,18 +76,15 @@ void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const ImportFormat import = { exts, true }; import_format.insert("fbx", import); } - { - Vector<String> exts; - exts.push_back("pmx"); - ImportFormat import = { exts, true }; - import_format.insert("mmd", 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); + _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 { +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)) { @@ -97,7 +101,8 @@ uint32_t EditorSceneImporterAssimp::get_import_flags() const { 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) { +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; std::wstring w_path = ProjectSettings::get_singleton()->globalize_path(p_path).c_str(); std::string s_path(w_path.begin(), w_path.end()); @@ -115,9 +120,11 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f //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_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_FlipWindingOrder | + // very important for culling so that it is done in the correct order. //aiProcess_DropNormals | //aiProcess_GenSmoothNormals | //aiProcess_JoinIdenticalVertices | @@ -132,8 +139,9 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f aiProcess_TransformUVCoords | aiProcess_FindInstances | //aiProcess_FixInfacingNormals | - aiProcess_ValidateDataStructure | + //aiProcess_ValidateDataStructure | aiProcess_OptimizeMeshes | + aiProcess_PopulateArmatureData | //aiProcess_OptimizeGraph | //aiProcess_Debone | // aiProcess_EmbedTextures | @@ -158,7 +166,8 @@ struct EditorSceneImporterAssetImportInterpolate { float t2 = t * t; float t3 = t2 * t; - return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); + return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * 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) { @@ -200,7 +209,8 @@ struct EditorSceneImporterAssetImportInterpolate<Quat> { }; template <class T> -T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp) { +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++) { @@ -272,48 +282,257 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co ERR_FAIL_V(p_values[0]); } -Spatial *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) { +aiBone *EditorSceneImporterAssimp::get_bone_from_stack(ImportState &state, aiString name) { + List<aiBone *>::Element *iter; + aiBone *bone = NULL; + 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 NULL; +} + +Spatial * +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 == NULL, NULL); ImportState state; state.path = p_path; state.assimp_scene = scene; state.max_bone_weights = p_max_bone_weights; - state.root = memnew(Spatial); - state.fbx = false; state.animation_player = NULL; - //fill light map cache - for (size_t l = 0; l < scene->mNumLights; l++) { + // populate light map + for (unsigned int l = 0; l < scene->mNumLights; l++) { aiLight *ai_light = scene->mLights[l]; ERR_CONTINUE(ai_light == NULL); state.light_cache[AssimpUtils::get_assimp_string(ai_light->mName)] = l; } - //fill camera cache - for (size_t c = 0; c < scene->mNumCameras; c++) { + // fill camera cache + for (unsigned int c = 0; c < scene->mNumCameras; c++) { aiCamera *ai_camera = scene->mCameras[c]; ERR_CONTINUE(ai_camera == NULL); state.camera_cache[AssimpUtils::get_assimp_string(ai_camera->mName)] = c; } if (scene->mRootNode) { + state.nodes.push_back(scene->mRootNode); - //generate nodes - for (uint32_t i = 0; i < scene->mRootNode->mNumChildren; i++) { - _generate_node(state, NULL, scene->mRootNode->mChildren[i], state.root); + // 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]); } - // finalize skeleton - for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) { - Skeleton *skeleton = key_value_pair->key(); - // convert world to local for skeleton bone rests - skeleton->localize_rests(); + RegenerateBoneStack(state); + + Node *last_valid_parent = NULL; + + 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); + + Spatial *spatial = NULL; + 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); + Skeleton *skeleton = memnew(Skeleton); + spatial = skeleton; + if (!state.armature_skeletons.has(element_assimp_node)) { + state.armature_skeletons.insert(element_assimp_node, skeleton); + } + } else if (bone != NULL) { + continue; + } else if (element_assimp_node->mNumMeshes > 0) { + spatial = memnew(Spatial); + } else { + spatial = memnew(Spatial); + } + + ERR_CONTINUE_MSG(spatial == NULL, "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 *, Spatial *>::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) { + Spatial *parent_node = parent_lookup->value(); + + ERR_FAIL_COND_V_MSG(parent_node == NULL, state.root, + "Parent node invalid even though lookup successful, out of ram?") + + if (parent_node && spatial != state.root) { + parent_node->add_child(spatial); + spatial->set_owner(state.root); + } else if (spatial == state.root) { + // required - think about it root never has a parent yet is valid, anything else without a parent is not valid. + } else // Safety for instances + { + WARN_PRINT( + "Failed to find parent node instance after lookup, serious warning report to godot with model"); + memdelete(spatial); // this node is broken + } + } 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 == NULL, "Armature for bone invalid: " + bone_name); + Skeleton *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); + skeleton->set_bone_pose(boneIdx, pform); + + if (parent_node != NULL) { + 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"); - generate_mesh_phase_from_skeletal_mesh(state); + + List<Spatial *> cleanup_template_nodes; + + for (Map<const aiNode *, Spatial *>::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(); + Spatial *mesh_template = key_value_pair->value(); + Node *parent_node = mesh_template->get_parent(); + + ERR_CONTINUE(assimp_node == NULL); + ERR_CONTINUE(mesh_template == NULL); + + if (mesh_template == state.root) { + continue; + } + + if (parent_node == NULL) { + 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) { + MeshInstance *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<Spatial *>::Element *element = cleanup_template_nodes.front(); element; element = element->next()) { + if (element->get()) { + memdelete(element->get()); + } + } } if (p_flags & IMPORT_ANIMATION && scene->mNumAnimations) { @@ -327,29 +546,39 @@ Spatial *EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScen } } + // + // 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 p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name) { - - const aiNodeAnim *assimp_track = assimp_anim->mChannels[p_track]; +void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id, + int anim_fps, Ref<Animation> animation, float ticks_per_second, + Skeleton *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, p_path); + animation->track_set_path(track_idx, node_path); //first determine animation length - float increment = 1.0 / float(p_bake_fps); + float increment = 1.0 / float(anim_fps); float time = 0.0; bool last = false; - int skeleton_bone = -1; - - if (p_skeleton) { - skeleton_bone = p_skeleton->find_bone(p_name); - } - Vector<Vector3> pos_values; Vector<float> pos_times; Vector<Vector3> scale_values; @@ -374,6 +603,7 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons 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; @@ -384,26 +614,34 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons } if (rot_values.size()) { - rot = _interpolate_track<Quat>(rot_times, rot_values, time, AssetImportAnimation::INTERP_LINEAR).normalized(); + 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_bone >= 0) { - Transform xform; - xform.basis.set_quat_scale(rot, scale); - xform.origin = pos; + if (skeleton) { + int skeleton_bone = skeleton->find_bone(node_name); - Transform rest_xform = p_skeleton->get_bone_rest(skeleton_bone); - xform = rest_xform.affine_inverse() * xform; - rot = xform.basis.get_rotation_quat(); - scale = xform.basis.get_scale(); - pos = xform.origin; - } + if (skeleton_bone >= 0 && track_bone) { - rot.normalize(); + Transform xform; + xform.basis.set_quat_scale(rot, scale); + xform.origin = pos; + + xform = skeleton->get_bone_pose(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); @@ -418,6 +656,53 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons } } +// 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 *, Spatial *>::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(); + Spatial *node = key_value_pair->value(); + + String node_name = AssimpUtils::get_assimp_string(assimp_node->mName); + if (name == node_name && node) { + return node; + } + } + return NULL; +} + +/* 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) == NULL) { + 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) { @@ -429,7 +714,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim 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 != NULL && Math::is_equal_approx(ticks_per_second, 0.0f)) { @@ -452,34 +737,60 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim animation->set_name(name); animation->set_length(anim->mDuration / ticks_per_second); - //regular tracks + // 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 } - for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) { - Skeleton *skeleton = key_value_pair->key(); - - bool is_bone = skeleton->find_bone(node_name) != -1; - //print_verbose("Bone " + node_name + " is bone? " + (is_bone ? "Yes" : "No")); - NodePath node_path; + Skeleton *skeleton = NULL; + NodePath node_path; + aiBone *bone = NULL; - if (is_bone) { - String path = state.root->get_path_to(skeleton); - path += ":" + node_name; - node_path = path; - } else { - ERR_CONTINUE(!state.node_map.has(node_name)); - Node *node = state.node_map[node_name]; - node_path = state.root->get_path_to(node); + // 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"); + } + } } + } - _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton, node_path, node_name); + // 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); + } } } @@ -494,10 +805,9 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim ERR_CONTINUE(prop_name.split("*").size() != 2); - ERR_CONTINUE(!state.node_map.has(mesh_name)); - - const MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(state.node_map[mesh_name]); - + Node *item = get_node_by_name(state, mesh_name); + ERR_CONTINUE_MSG(!item, "failed to look up node by name"); + const MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(item); ERR_CONTINUE(mesh_instance == NULL); String base_path = state.root->get_path_to(mesh_instance); @@ -528,15 +838,13 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim 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, - Skeleton *p_skeleton) { +Ref<Mesh> +EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, + const aiNode *assimp_node, Ref<Skin> &skin, + Skeleton *&skeleton_assigned) { Ref<ArrayMesh> mesh; mesh.instance(); @@ -548,7 +856,6 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( 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); @@ -560,7 +867,6 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( } } } - // // Process Vertex Weights // @@ -570,19 +876,30 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( Map<uint32_t, Vector<BoneInfo> > vertex_weights; - if (p_skeleton) { + if (ai_mesh->mNumBones > 0) { for (size_t b = 0; b < ai_mesh->mNumBones; b++) { aiBone *bone = ai_mesh->mBones[b]; - String bone_name = AssimpUtils::get_assimp_string(bone->mName); - int bone_index = p_skeleton->find_bone(bone_name); - ERR_CONTINUE(bone_index == -1); //bone refers to an unexisting index, wtf. + 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; @@ -619,7 +936,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( // 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); + Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b, + ai_mesh->mColors[0]->a); st->add_color(color); } @@ -685,6 +1003,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) { if (mat_two_sided > 0) { mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); + } else { + mat->set_cull_mode(SpatialMaterial::CULL_BACK); } } @@ -697,7 +1017,7 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( // Culling handling for meshes // cull all back faces - mat->set_cull_mode(SpatialMaterial::CULL_BACK); + mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // Now process materials aiTextureType base_color = aiTextureType_BASE_COLOR; @@ -712,7 +1032,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); - mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + mat->set_cull_mode( + SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode } mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture); @@ -731,7 +1052,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); - mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + mat->set_cull_mode( + SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode } mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture); @@ -742,7 +1064,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) { mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); - mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + mat->set_cull_mode( + SpatialMaterial::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)); } @@ -838,7 +1161,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( } 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 (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(SpatialMaterial::FEATURE_EMISSION, true); mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture); @@ -981,62 +1305,27 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices( return mesh; } -/* to be moved 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 NULL; -} - /** * Create a new mesh for the node supplied */ -void EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform) { +MeshInstance * +EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform) { /* MESH NODE */ Ref<Mesh> mesh; - Skeleton *skeleton = NULL; + Ref<Skin> skin; // see if we have mesh cache for this. Vector<int> surface_indices; - for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) { - int mesh_index = assimp_node->mMeshes[i]; - aiMesh *ai_mesh = state.assimp_scene->mMeshes[assimp_node->mMeshes[i]]; - // Map<aiBone*, Skeleton*> // this is what we need - if (ai_mesh->mNumBones > 0) { - // we only need the first bone to retrieve the skeleton - const aiBone *first = ai_mesh->mBones[0]; - - ERR_FAIL_COND(first == NULL); + RegenerateBoneStack(state); - Map<const aiBone *, Skeleton *>::Element *match = state.bone_to_skeleton_lookup.find(first); - if (match != NULL) { - skeleton = match->value(); - - if (skeleton == NULL) { - print_error("failed to find bone skeleton for bone: " + AssimpUtils::get_assimp_string(first->mName)); - } else { - print_verbose("successfully found skeleton for first bone on mesh, can properly handle animations now!"); - } - // I really need the skeleton and bone to be known as this is something flaky in model exporters. - ERR_FAIL_COND(skeleton == NULL); // should not happen if bone was successfully created in previous step. - } - } + // Configure indicies + 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(); + //surface_indices.sort(); String mesh_key; for (int i = 0; i < surface_indices.size(); i++) { if (i > 0) { @@ -1045,262 +1334,154 @@ void EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *as mesh_key += itos(surface_indices[i]); } + Skeleton *skeleton = NULL; + aiNode *armature = NULL; + if (!state.mesh_cache.has(mesh_key)) { - mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skeleton); + mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skin, skeleton); state.mesh_cache[mesh_key] = mesh; } - //Transform transform = recursive_state.node_transform; - - // we must unfortunately overwrite mesh and skeleton transform with armature data - if (skeleton != NULL) { - print_verbose("Applying mesh and skeleton to armature"); - // required for blender, maya etc - Map<Skeleton *, const Spatial *>::Element *match = state.armature_skeletons.find(skeleton); - node_transform = match->value()->get_transform(); - } - MeshInstance *mesh_node = memnew(MeshInstance); mesh = state.mesh_cache[mesh_key]; mesh_node->set_mesh(mesh); - attach_new_node(state, - mesh_node, - assimp_node, - parent_node, - node_name, - node_transform); - - // set this once and for all - if (skeleton != NULL) { - // root must be informed of its new child - parent_node->add_child(skeleton); + // 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; + } - // owner must be set after adding to tree - skeleton->set_owner(state.root); + 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); - skeleton->set_transform(node_transform); + skin->add_bind(bind_count, t); + skin->set_bind_bone(bind_count, id); + bind_count++; + } + } + } + } - // must be done after added to tree - mesh_node->set_skeleton_path(mesh_node->get_path_to(skeleton)); + print_verbose("Finished configuring bind pose for skin mesh"); } -} - -/** generate_mesh_phase_from_skeletal_mesh - * This must be executed after generate_nodes because the skeleton doesn't exist until that has completed the first pass - */ -void EditorSceneImporterAssimp::generate_mesh_phase_from_skeletal_mesh(ImportState &state) { - // prevent more than one skeleton existing per mesh - // * multiple root bones have this - // * this simply filters the node out if it has already been added then references the skeleton so we know the actual skeleton for this node - for (Map<const aiNode *, const Node *>::Element *key_value_pair = state.assimp_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) { - const aiNode *assimp_node = key_value_pair->key(); - Node *current_node = (Node *)key_value_pair->value(); - Node *parent_node = current_node->get_parent(); - ERR_CONTINUE(assimp_node == NULL); - ERR_CONTINUE(parent_node == NULL); - - String node_name = AssimpUtils::get_assimp_string(assimp_node->mName); - Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation); + // 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 (assimp_node->mNumMeshes > 0) { - create_mesh(state, assimp_node, node_name, current_node, parent_node, node_transform); - } + 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); } -} -/** - * attach_new_node - * configures node, assigns parent node -**/ -void EditorSceneImporterAssimp::attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform) { - ERR_FAIL_COND(new_node == NULL); - ERR_FAIL_COND(node == NULL); - ERR_FAIL_COND(parent_node == NULL); - ERR_FAIL_COND(state.root == NULL); - - // assign properties to new godot note - new_node->set_name(Name); - new_node->set_transform(transform); - - // add element as child to parent - parent_node->add_child(new_node); - - // owner must be set after - new_node->set_owner(state.root); - - // cache node mapping results by name and then by aiNode* - state.node_map[Name] = new_node; - state.assimp_node_map[node] = new_node; + return mesh_node; } /** * Create a light for the scene * Automatically caches lights for lookup later */ -void EditorSceneImporterAssimp::create_light(ImportState &state, RecursiveState &recursive_state) { +Spatial *EditorSceneImporterAssimp::create_light( + ImportState &state, + const String &node_name, + Transform &look_at_transform) { Light *light = NULL; - aiLight *ai_light = state.assimp_scene->mLights[state.light_cache[recursive_state.node_name]]; - ERR_FAIL_COND(!ai_light); + aiLight *assimp_light = state.assimp_scene->mLights[state.light_cache[node_name]]; + ERR_FAIL_COND_V(!assimp_light, NULL); - if (ai_light->mType == aiLightSource_DIRECTIONAL) { + if (assimp_light->mType == aiLightSource_DIRECTIONAL) { light = memnew(DirectionalLight); - Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z); - dir.normalize(); - Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z); - Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z); - up.normalize(); - - Transform light_transform; - light_transform.set_look_at(pos, pos + dir, up); - - recursive_state.node_transform *= light_transform; - - } else if (ai_light->mType == aiLightSource_POINT) { + } else if (assimp_light->mType == aiLightSource_POINT) { light = memnew(OmniLight); - Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z); - Transform xform; - xform.origin = pos; - - recursive_state.node_transform *= xform; - - light->set_transform(xform); - - //light->set_param(Light::PARAM_ATTENUATION, 1); - } else if (ai_light->mType == aiLightSource_SPOT) { + } else if (assimp_light->mType == aiLightSource_SPOT) { light = memnew(SpotLight); - - Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z); - dir.normalize(); - Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z); - Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z); - up.normalize(); - - Transform light_transform; - light_transform.set_look_at(pos, pos + dir, up); - recursive_state.node_transform *= light_transform; - - //light->set_param(Light::PARAM_ATTENUATION, 0.0f); } - ERR_FAIL_COND(light == NULL); + ERR_FAIL_COND_V(light == NULL, NULL); + + 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(ai_light->mColorDiffuse.r, ai_light->mColorDiffuse.g, ai_light->mColorDiffuse.b)); - recursive_state.new_node = light; + light->set_color( + Color(assimp_light->mColorDiffuse.r, assimp_light->mColorDiffuse.g, assimp_light->mColorDiffuse.b)); - attach_new_node(state, - recursive_state.new_node, - recursive_state.assimp_node, - recursive_state.parent_node, - recursive_state.node_name, - recursive_state.node_transform); + return light; } /** * Create camera for the scene */ -void EditorSceneImporterAssimp::create_camera(ImportState &state, RecursiveState &recursive_state) { - aiCamera *ai_camera = state.assimp_scene->mCameras[state.camera_cache[recursive_state.node_name]]; - ERR_FAIL_COND(!ai_camera); - - Camera *camera = memnew(Camera); - - float near = ai_camera->mClipPlaneNear; +Spatial *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, NULL); + + Camera *camera_node = memnew(Camera); + ERR_FAIL_COND_V(!camera_node, NULL); + float near = camera->mClipPlaneNear; if (Math::is_equal_approx(near, 0.0f)) { near = 0.1f; } - camera->set_perspective(Math::rad2deg(ai_camera->mHorizontalFOV) * 2.0f, near, ai_camera->mClipPlaneFar); + 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); - Vector3 pos = Vector3(ai_camera->mPosition.x, ai_camera->mPosition.y, ai_camera->mPosition.z); - Vector3 look_at = Vector3(ai_camera->mLookAt.y, ai_camera->mLookAt.x, ai_camera->mLookAt.z).normalized(); - Vector3 up = Vector3(ai_camera->mUp.x, ai_camera->mUp.y, ai_camera->mUp.z); - - Transform xform; - xform.set_look_at(pos, look_at, up); - - recursive_state.new_node = camera; - - attach_new_node(state, - recursive_state.new_node, - recursive_state.assimp_node, - recursive_state.parent_node, - recursive_state.node_name, - recursive_state.node_transform); -} - -/** - * Create Bone - * Create a bone in the scene - */ -void EditorSceneImporterAssimp::create_bone(ImportState &state, RecursiveState &recursive_state) { - // for each armature node we must make a new skeleton but ensure it - // has a bone in the child to ensure we don't make too many - // the reason you must do this is because a skeleton exists per mesh? - // and duplicate bone names are very bad for determining what is going on. - aiBone *parent_bone_assimp = get_bone_by_name(state.assimp_scene, recursive_state.assimp_node->mParent->mName); - - // set to true when you want to use skeleton reference from cache. - bool do_not_create_armature = false; - - // prevent more than one skeleton existing per mesh - // * multiple root bones have this - // * this simply filters the node out if it has already been added then references the skeleton so we know the actual skeleton for this node - for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) { - if (key_value_pair->value() == recursive_state.parent_node) { - // apply the skeleton for this mesh - recursive_state.skeleton = key_value_pair->key(); - - // force this off - do_not_create_armature = true; - } - } - - // check if parent was a bone - // if parent was not a bone this is the first bone. - // therefore parent is the 'armature'? - // also for multi root bone support make sure we don't already have the skeleton cached. - // if we do we must merge them - as this is all godot supports right now. - if (!parent_bone_assimp && recursive_state.skeleton == NULL && !do_not_create_armature) { - // create new skeleton on the root. - recursive_state.skeleton = memnew(Skeleton); - - ERR_FAIL_COND(state.root == NULL); - ERR_FAIL_COND(recursive_state.skeleton == NULL); - - print_verbose("Parent armature node is called " + recursive_state.parent_node->get_name()); - // store root node for this skeleton / used in animation playback and bone detection. - - state.armature_skeletons.insert(recursive_state.skeleton, Object::cast_to<Spatial>(recursive_state.parent_node)); - - //skeleton->set_use_bones_in_world_transform(true); - print_verbose("Created new FBX skeleton for armature node"); - } - - ERR_FAIL_COND_MSG(recursive_state.skeleton == NULL, "Mesh has invalid armature detection - report this"); - - // this transform is a bone - recursive_state.skeleton->add_bone(recursive_state.node_name); - - //ERR_FAIL_COND(recursive_state.skeleton->get_name() == ""); - print_verbose("Bone added to lookup: " + AssimpUtils::get_assimp_string(recursive_state.bone->mName)); - print_verbose("Skeleton attached to: " + recursive_state.skeleton->get_name()); - // make sure to write the bone lookup inverse so we can retrieve the mesh for this bone later - state.bone_to_skeleton_lookup.insert(recursive_state.bone, recursive_state.skeleton); - - Transform xform = AssimpUtils::assimp_matrix_transform(recursive_state.bone->mOffsetMatrix); - recursive_state.skeleton->set_bone_rest(recursive_state.skeleton->get_bone_count() - 1, xform.affine_inverse()); - - // get parent node of assimp node - const aiNode *parent_node_assimp = recursive_state.assimp_node->mParent; - - // ensure we have a parent - if (parent_node_assimp != NULL) { - int parent_bone_id = recursive_state.skeleton->find_bone(AssimpUtils::get_assimp_string(parent_node_assimp->mName)); - int current_bone_id = recursive_state.skeleton->find_bone(recursive_state.node_name); - print_verbose("Parent bone id " + itos(parent_bone_id) + " current bone id" + itos(current_bone_id)); - print_verbose("Bone debug: " + AssimpUtils::get_assimp_string(parent_node_assimp->mName)); - recursive_state.skeleton->set_bone_parent(current_bone_id, parent_bone_id); - } + look_at_transform.set_look_at(pos + look_at_transform.origin, look_at, up); + return camera_node; } /** @@ -1309,46 +1490,30 @@ void EditorSceneImporterAssimp::create_bone(ImportState &state, RecursiveState & */ void EditorSceneImporterAssimp::_generate_node( ImportState &state, - Skeleton *skeleton, - const aiNode *assimp_node, Node *parent_node) { + const aiNode *assimp_node) { - // sanity check - ERR_FAIL_COND(state.root == NULL); - ERR_FAIL_COND(state.assimp_scene == NULL); ERR_FAIL_COND(assimp_node == NULL); - ERR_FAIL_COND(parent_node == NULL); - - Spatial *new_node = NULL; + state.nodes.push_back(assimp_node); String node_name = AssimpUtils::get_assimp_string(assimp_node->mName); - Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation); - - // can safely return null - is this node a bone? - aiBone *bone = get_bone_by_name(state.assimp_scene, assimp_node->mName); - - // out arguments helper - for pushing state down into creation functions - RecursiveState recursive_state(node_transform, skeleton, new_node, node_name, assimp_node, parent_node, bone); - - // Creation code - if (state.light_cache.has(node_name)) { - create_light(state, recursive_state); - } else if (state.camera_cache.has(node_name)) { - create_camera(state, recursive_state); - } else if (bone != NULL) { - create_bone(state, recursive_state); - } else { - //generic node - recursive_state.new_node = memnew(Spatial); - attach_new_node(state, - recursive_state.new_node, - recursive_state.assimp_node, - recursive_state.parent_node, - recursive_state.node_name, - recursive_state.node_transform); + 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 == NULL && current_bone) { + state.armature_nodes.push_back(assimp_node->mParent); + print_verbose("found valid armature: " + parent_name); } - // recurse into all child elements - for (size_t i = 0; i < recursive_state.assimp_node->mNumChildren; i++) { - _generate_node(state, recursive_state.skeleton, recursive_state.assimp_node->mChildren[i], - recursive_state.new_node != NULL ? recursive_state.new_node : recursive_state.parent_node); + 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 index 787376c9af..a47d7ac46e 100644 --- a/modules/assimp/editor_scene_importer_assimp.h +++ b/modules/assimp/editor_scene_importer_assimp.h @@ -50,6 +50,7 @@ #include <assimp/DefaultLogger.hpp> #include <assimp/LogStream.hpp> #include <assimp/Logger.hpp> +#include <map> #include "import_state.h" #include "import_utils.h" @@ -72,7 +73,6 @@ public: class EditorSceneImporterAssimp : public EditorSceneImporter { private: GDCLASS(EditorSceneImporterAssimp, EditorSceneImporter); - const String ASSIMP_FBX_KEY = "_$AssimpFbx$"; struct AssetImportAnimation { enum Interpolation { @@ -88,40 +88,32 @@ private: float weight; }; - struct SkeletonHole { //nodes may be part of the skeleton by used by vertex - String name; - String parent; - Transform pose; - const aiNode *node; - }; - - void _calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w); - void _set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<Texture> texture); + Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, + const aiNode *assimp_node, Ref<Skin> &skin, + Skeleton *&skeleton_assigned); - Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, const aiNode *assimp_node, Skeleton *p_skeleton = NULL); - - // utility for node creation - void attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform); // simple object creation functions - void create_light(ImportState &state, RecursiveState &recursive_state); - void create_camera(ImportState &state, RecursiveState &recursive_state); - void create_bone(ImportState &state, RecursiveState &recursive_state); + Spatial *create_light(ImportState &state, + const String &node_name, + Transform &look_at_transform); + Spatial *create_camera( + ImportState &state, + const String &node_name, + Transform &look_at_transform); // non recursive - linear so must not use recursive arguments - void create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform); - + MeshInstance *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, Skeleton *skeleton, const aiNode *assimp_node, Node *parent_node); - // runs after _generate_node as it must then use pre-created godot skeleton. - void generate_mesh_phase_from_skeletal_mesh(ImportState &state); - void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name); + 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, + Skeleton *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); Spatial *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights); - String _assimp_anim_string_to_string(const aiString &p_string) const; - String _assimp_raw_string_to_string(const aiString &p_string) const; - float _get_fbx_fps(int32_t time_mode, const aiScene *p_scene); 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; @@ -148,6 +140,10 @@ public: virtual uint32_t get_import_flags() const; virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL); 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/import_state.h b/modules/assimp/import_state.h index 56d89ffea7..9859a88c1c 100644 --- a/modules/assimp/import_state.h +++ b/modules/assimp/import_state.h @@ -52,28 +52,42 @@ namespace AssimpImporter { /** Import state is for global scene import data - * This makes the code simpler and contains useful lookups. - */ + * This makes the code simpler and contains useful lookups. + */ struct ImportState { String path; + Spatial *root; const aiScene *assimp_scene; uint32_t max_bone_weights; - Spatial *root; Map<String, Ref<Mesh> > mesh_cache; Map<int, Ref<Material> > material_cache; Map<String, int> light_cache; Map<String, int> camera_cache; - //Vector<Skeleton *> skeletons; - Map<Skeleton *, const Spatial *> armature_skeletons; // maps skeletons based on their armature nodes. - Map<const aiBone *, Skeleton *> bone_to_skeleton_lookup; // maps bones back into their skeleton + // very useful for when you need to ask assimp for the bone mesh - Map<String, Node *> node_map; - Map<const aiNode *, const Node *> assimp_node_map; + + Map<const aiNode *, Node *> assimp_node_map; Map<String, Ref<Image> > path_to_image_cache; - bool fbx; //for some reason assimp does some things different for FBX + + // Generation 3 - determinisitic iteration + // to lower potential recursion errors + List<const aiNode *> nodes; + Map<const aiNode *, Spatial *> 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 *, Skeleton *> armature_skeletons; + Map<aiBone *, Skeleton *> 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; }; struct AssimpImageData { @@ -86,14 +100,15 @@ struct AssimpImageData { * 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, Skeleton *_skeleton, Spatial *_new_node, - const String &_node_name, - const aiNode *_assimp_node, + String &_node_name, + aiNode *_assimp_node, Node *_parent_node, - const aiBone *_bone) : + aiBone *_bone) : node_transform(_node_transform), skeleton(_skeleton), new_node(_new_node), @@ -102,13 +117,13 @@ struct RecursiveState { parent_node(_parent_node), bone(_bone) {} - Transform &node_transform; - Skeleton *skeleton; - Spatial *new_node; - const String &node_name; - const aiNode *assimp_node; - Node *parent_node; - const aiBone *bone; + Transform node_transform; + Skeleton *skeleton = NULL; + Spatial *new_node = NULL; + String node_name; + aiNode *assimp_node = NULL; + Node *parent_node = NULL; + aiBone *bone = NULL; }; } // namespace AssimpImporter diff --git a/thirdparty/README.md b/thirdparty/README.md index 434006ac6b..8928009817 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -4,7 +4,7 @@ ## assimp - Upstream: http://github.com/assimp/assimp -- Version: git (1d565b0aab5a2ee00462f18c5b8a81f6a5454a48) +- Version: git (308db73d0b3c2d1870cd3e465eaa283692a4cf23) - License: BSD-3-Clause diff --git a/thirdparty/assimp/code/Common/BaseImporter.cpp b/thirdparty/assimp/code/Common/BaseImporter.cpp index de5018a250..5c1e605549 100644 --- a/thirdparty/assimp/code/Common/BaseImporter.cpp +++ b/thirdparty/assimp/code/Common/BaseImporter.cpp @@ -67,7 +67,20 @@ using namespace Assimp; // Constructor to be privately used by Importer BaseImporter::BaseImporter() AI_NO_EXCEPT : m_progress() { - // nothing to do here + /** + * 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; } // ------------------------------------------------------------------------------------------------ @@ -85,7 +98,7 @@ void BaseImporter::UpdateImporterScale( Importer* pImp ) double activeScale = importerScale * fileScale; // Set active scaling - pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale); + pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) ); ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale ); } diff --git a/thirdparty/assimp/code/Common/DefaultIOSystem.cpp b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp index d40b67de32..6fdc24dd80 100644 --- a/thirdparty/assimp/code/Common/DefaultIOSystem.cpp +++ b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp @@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; -// maximum path length -// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html -#ifdef PATH_MAX -# define PATHLIMIT PATH_MAX -#else -# define PATHLIMIT 4096 +#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 +bool DefaultIOSystem::Exists(const char* pFile) const { #ifdef _WIN32 - wchar_t fileName16[PATHLIMIT]; - -#ifndef WindowsStore - bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0; - if (isUnicode) { - - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT); - struct __stat64 filestat; - if (0 != _wstat64(fileName16, &filestat)) { - return false; - } - } else { -#endif - FILE* file = ::fopen(pFile, "rb"); - if (!file) - return false; - - ::fclose(file); -#ifndef WindowsStore + struct __stat64 filestat; + if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) { + return false; } -#endif #else - FILE* file = ::fopen( pFile, "rb"); - if( !file) + FILE* file = ::fopen(pFile, "rb"); + if (!file) return false; - ::fclose( file); + ::fclose(file); #endif return true; } // ------------------------------------------------------------------------------------------------ // Open a new file with a given path. -IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode) +IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode) { - ai_assert(NULL != strFile); - ai_assert(NULL != strMode); + ai_assert(strFile != nullptr); + ai_assert(strMode != nullptr); FILE* file; #ifdef _WIN32 - wchar_t fileName16[PATHLIMIT]; -#ifndef WindowsStore - bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0; - if (isUnicode) { - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT); - std::string mode8(strMode); - file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str()); - } else { -#endif - file = ::fopen(strFile, strMode); -#ifndef WindowsStore - } -#endif + file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str()); #else file = ::fopen(strFile, strMode); #endif - if (nullptr == file) + if (!file) return nullptr; - return new DefaultIOStream(file, (std::string) strFile); + return new DefaultIOStream(file, strFile); } // ------------------------------------------------------------------------------------------------ // Closes the given file and releases all resources associated with it. -void DefaultIOSystem::Close( IOStream* pFile) +void DefaultIOSystem::Close(IOStream* pFile) { delete pFile; } @@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const // ------------------------------------------------------------------------------------------------ // IOSystem default implementation (ComparePaths isn't a pure virtual function) -bool IOSystem::ComparePaths (const char* one, const char* second) const +bool IOSystem::ComparePaths(const char* one, const char* second) const { - return !ASSIMP_stricmp(one,second); + return !ASSIMP_stricmp(one, second); } // ------------------------------------------------------------------------------------------------ // Convert a relative path into an absolute path -inline static void MakeAbsolutePath (const char* in, char* _out) +inline static std::string MakeAbsolutePath(const char* in) { - ai_assert(in && _out); -#if defined( _MSC_VER ) || defined( __MINGW32__ ) -#ifndef WindowsStore - bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0; - if (isUnicode) { - wchar_t out16[PATHLIMIT]; - wchar_t in16[PATHLIMIT]; - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT); - wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT); - if (ret) { - WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr); - } - 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)); - strcpy(_out, in); - } - - } else { -#endif - char* ret = :: _fullpath(_out, in, PATHLIMIT); - 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)); - strcpy(_out, in); - } -#ifndef WindowsStore + 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); } -#endif #else - // use realpath - char* ret = realpath(in, _out); - if(!ret) { + 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)); - strcpy(_out,in); + out = in; } -#endif + return out; } // ------------------------------------------------------------------------------------------------ // DefaultIOSystem's more specialized implementation -bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const +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) ) + if (!ASSIMP_stricmp(one, second)) return true; - char temp1[PATHLIMIT]; - char temp2[PATHLIMIT]; - - MakeAbsolutePath (one, temp1); - MakeAbsolutePath (second, temp2); + std::string temp1 = MakeAbsolutePath(one); + std::string temp2 = MakeAbsolutePath(second); - return !ASSIMP_stricmp(temp1,temp2); + return !ASSIMP_stricmp(temp1, temp2); } // ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::fileName( const std::string &path ) +std::string DefaultIOSystem::fileName(const std::string& path) { std::string ret = path; std::size_t last = ret.find_last_of("\\/"); @@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path ) } // ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::completeBaseName( const std::string &path ) +std::string DefaultIOSystem::completeBaseName(const std::string& path) { std::string ret = fileName(path); std::size_t pos = ret.find_last_of('.'); - if(pos != ret.npos) ret = ret.substr(0, pos); + if (pos != std::string::npos) ret = ret.substr(0, pos); return ret; } // ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::absolutePath( const std::string &path ) +std::string DefaultIOSystem::absolutePath(const std::string& path) { std::string ret = path; std::size_t last = ret.find_last_of("\\/"); @@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path ) } // ------------------------------------------------------------------------------------------------ - -#undef PATHLIMIT diff --git a/thirdparty/assimp/code/Common/Exporter.cpp b/thirdparty/assimp/code/Common/Exporter.cpp index 090b561ae0..4ce1a2bd80 100644 --- a/thirdparty/assimp/code/Common/Exporter.cpp +++ b/thirdparty/assimp/code/Common/Exporter.cpp @@ -102,6 +102,8 @@ void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperti 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*); // ------------------------------------------------------------------------------------------------ @@ -179,6 +181,11 @@ Exporter::ExportFormatEntry gExporters[] = 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 @@ -316,34 +323,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha } // ------------------------------------------------------------------------------------------------ -bool IsVerboseFormat(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 IsVerboseFormat(const aiScene* pScene) { - for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - if(!IsVerboseFormat(pScene->mMeshes[i])) { - return false; - } - } - - return true; -} - -// ------------------------------------------------------------------------------------------------ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties) { ASSIMP_BEGIN_EXCEPTION_REGION(); @@ -352,7 +331,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c // 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) || IsVerboseFormat(pScene); + const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene); pimpl->mProgressHandler->UpdateFileWrite(0, 4); @@ -472,7 +451,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c } ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry. - exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties); + 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) { diff --git a/thirdparty/assimp/code/Common/ImporterRegistry.cpp b/thirdparty/assimp/code/Common/ImporterRegistry.cpp index 32ac3b4168..b9f28f0356 100644 --- a/thirdparty/assimp/code/Common/ImporterRegistry.cpp +++ b/thirdparty/assimp/code/Common/ImporterRegistry.cpp @@ -197,6 +197,9 @@ corresponding preprocessor flag to selectively disable formats. #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 @@ -223,6 +226,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) #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 diff --git a/thirdparty/assimp/code/Common/PostStepRegistry.cpp b/thirdparty/assimp/code/Common/PostStepRegistry.cpp index ef58f8ddfd..8ff4af0400 100644 --- a/thirdparty/assimp/code/Common/PostStepRegistry.cpp +++ b/thirdparty/assimp/code/Common/PostStepRegistry.cpp @@ -131,11 +131,15 @@ corresponding preprocessor flag to selectively disable steps. #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 { // ------------------------------------------------------------------------------------------------ @@ -180,6 +184,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #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 diff --git a/thirdparty/assimp/code/Common/SceneCombiner.cpp b/thirdparty/assimp/code/Common/SceneCombiner.cpp index e445bd7434..f7b13cc951 100644 --- a/thirdparty/assimp/code/Common/SceneCombiner.cpp +++ b/thirdparty/assimp/code/Common/SceneCombiner.cpp @@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) { 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); } // ------------------------------------------------------------------------------------------------ @@ -1167,6 +1196,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) { // and reallocate all arrays CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels ); + CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels ); } // ------------------------------------------------------------------------------------------------ @@ -1186,6 +1216,26 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) { 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 ) { diff --git a/thirdparty/assimp/code/Common/Version.cpp b/thirdparty/assimp/code/Common/Version.cpp index cc94340ac8..cf1da7d5ba 100644 --- a/thirdparty/assimp/code/Common/Version.cpp +++ b/thirdparty/assimp/code/Common/Version.cpp @@ -46,8 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assimp/scene.h> #include "ScenePrivate.h" -static const unsigned int MajorVersion = 4; -static const unsigned int MinorVersion = 1; +#include "revision.h" // -------------------------------------------------------------------------------- // Legal information string - don't remove this. @@ -56,9 +55,9 @@ 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) 2008-2017, assimp team\n" +"(c) 2006-2019, assimp team\n" "License under the terms and conditions of the 3-clause BSD license\n" -"http://assimp.sourceforge.net\n" +"http://assimp.org\n" ; // ------------------------------------------------------------------------------------------------ @@ -70,13 +69,13 @@ ASSIMP_API const char* aiGetLegalString () { // ------------------------------------------------------------------------------------------------ // Get Assimp minor version ASSIMP_API unsigned int aiGetVersionMinor () { - return MinorVersion; + return VER_MINOR; } // ------------------------------------------------------------------------------------------------ // Get Assimp major version ASSIMP_API unsigned int aiGetVersionMajor () { - return MajorVersion; + return VER_MAJOR; } // ------------------------------------------------------------------------------------------------ @@ -104,9 +103,6 @@ ASSIMP_API unsigned int aiGetCompileFlags () { return flags; } -// include current build revision, which is even updated from time to time -- :-) -#include "revision.h" - // ------------------------------------------------------------------------------------------------ ASSIMP_API unsigned int aiGetVersionRevision() { return GitVersion; diff --git a/thirdparty/assimp/code/Common/scene.cpp b/thirdparty/assimp/code/Common/scene.cpp index 2acb348d81..d15619acff 100644 --- a/thirdparty/assimp/code/Common/scene.cpp +++ b/thirdparty/assimp/code/Common/scene.cpp @@ -44,23 +44,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. aiNode::aiNode() : mName("") -, mParent(NULL) +, mParent(nullptr) , mNumChildren(0) -, mChildren(NULL) +, mChildren(nullptr) , mNumMeshes(0) -, mMeshes(NULL) -, mMetaData(NULL) { +, mMeshes(nullptr) +, mMetaData(nullptr) { // empty } aiNode::aiNode(const std::string& name) : mName(name) -, mParent(NULL) +, mParent(nullptr) , mNumChildren(0) -, mChildren(NULL) +, mChildren(nullptr) , mNumMeshes(0) -, mMeshes(NULL) -, mMetaData(NULL) { +, mMeshes(nullptr) +, mMetaData(nullptr) { // empty } @@ -68,7 +68,7 @@ aiNode::aiNode(const std::string& name) aiNode::~aiNode() { // delete all children recursively // to make sure we won't crash if the data is invalid ... - if (mChildren && mNumChildren) + if (mNumChildren && mChildren) { for (unsigned int a = 0; a < mNumChildren; a++) delete mChildren[a]; diff --git a/thirdparty/assimp/code/FBX/FBXCompileConfig.h b/thirdparty/assimp/code/FBX/FBXCompileConfig.h index 3a3841fa5b..03536a1823 100644 --- a/thirdparty/assimp/code/FBX/FBXCompileConfig.h +++ b/thirdparty/assimp/code/FBX/FBXCompileConfig.h @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_AI_FBX_COMPILECONFIG_H #include <map> +#include <set> // #if _MSC_VER > 1500 || (defined __GNUC___) @@ -54,16 +55,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 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 diff --git a/thirdparty/assimp/code/FBX/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp index 3f64016ea4..d8a22d9f74 100644 --- a/thirdparty/assimp/code/FBX/FBXConverter.cpp +++ b/thirdparty/assimp/code/FBX/FBXConverter.cpp @@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXImporter.h" #include <assimp/StringComparison.h> +#include <assimp/MathFunctions.h> #include <assimp/scene.h> @@ -67,7 +68,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sstream> #include <iomanip> #include <cstdint> - +#include <iostream> +#include <stdlib.h> namespace Assimp { namespace FBX { @@ -76,7 +78,7 @@ namespace Assimp { #define MAGIC_NODE_TAG "_$AssimpFbx$" -#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L +#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones ) : defaultMaterialIndex() @@ -95,6 +97,14 @@ namespace Assimp { // 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) { @@ -144,7 +154,7 @@ namespace Assimp { out->mRootNode->mName.Set(unique_name); // root has ID 0 - ConvertNodes(0L, *out->mRootNode); + ConvertNodes(0L, out->mRootNode, out->mRootNode); } static std::string getAncestorBaseName(const aiNode* node) @@ -178,8 +188,11 @@ namespace Assimp { GetUniqueName(original_name, unique_name); return unique_name; } - - void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) { + /// 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; @@ -190,62 +203,69 @@ namespace Assimp { try { for (const Connection* con : conns) { - // ignore object-property links if (con->PropertyName().length()) { - continue; + // 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::LogWarn("failed to convert source object for Model link"); + 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_transform; - - std::string unique_name = MakeUniqueNodeName(model, parent); - + 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. - const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain); + + // 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(unique_name)); + 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* prenode : nodes_chain) { - ai_assert(prenode); + aiNode* last_parent = parent; + for (aiNode* child : nodes_chain) { + ai_assert(child); - if (last_parent != &parent) { + if (last_parent != parent) { last_parent->mNumChildren = 1; last_parent->mChildren = new aiNode*[1]; - last_parent->mChildren[0] = prenode; + last_parent->mChildren[0] = child; } - prenode->mParent = last_parent; - last_parent = prenode; + child->mParent = last_parent; + last_parent = child; - new_abs_transform *= prenode->mTransformation; + new_abs_transform *= child->mTransformation; } // attach geometry - ConvertModel(*model, *nodes_chain.back(), new_abs_transform); + 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 @@ -257,7 +277,7 @@ namespace Assimp { for (aiNode* postnode : post_nodes_chain) { ai_assert(postnode); - if (last_parent != &parent) { + if (last_parent != parent) { last_parent->mNumChildren = 1; last_parent->mChildren = new aiNode*[1]; last_parent->mChildren[0] = postnode; @@ -279,15 +299,15 @@ namespace Assimp { ); } - // attach sub-nodes (if any) - ConvertNodes(model->ID(), *last_parent, new_abs_transform); + // recursion call - child nodes + ConvertNodes(model->ID(), last_parent, root_node); if (doc.Settings().readLights) { - ConvertLights(*model, unique_name); + ConvertLights(*model, node_name); } if (doc.Settings().readCameras) { - ConvertCameras(*model, unique_name); + ConvertCameras(*model, node_name); } nodes.push_back(nodes_chain.front()); @@ -296,11 +316,17 @@ namespace Assimp { } if (nodes.size()) { - parent.mChildren = new aiNode*[nodes.size()](); - parent.mNumChildren = static_cast<unsigned int>(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); + std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren); } + else + { + parent->mNumChildren = 0; + parent->mChildren = nullptr; + } + } catch (std::exception&) { Util::delete_fun<aiNode> deleter; @@ -553,7 +579,7 @@ namespace Assimp { return; } - const float angle_epsilon = 1e-6f; + const float angle_epsilon = Math::getEpsilon<float>(); out = aiMatrix4x4(); @@ -694,7 +720,7 @@ namespace Assimp { std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4()); // generate transformation matrices for all the different transformation components - const float zero_epsilon = 1e-6f; + 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); @@ -802,7 +828,7 @@ namespace Assimp { // 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)); + //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 @@ -904,7 +930,8 @@ namespace Assimp { } } - void FBXConverter::ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform) + void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, + const aiMatrix4x4 &absolute_transform) { const std::vector<const Geometry*>& geos = model.GetGeometry(); @@ -916,11 +943,12 @@ namespace Assimp { 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, node_global_transform, nd); + 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, node_global_transform, nd); + const std::vector<unsigned int>& indices = ConvertLine(*line, model, parent, root_node); std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); } else { @@ -929,15 +957,16 @@ namespace Assimp { } if (meshes.size()) { - nd.mMeshes = new unsigned int[meshes.size()](); - nd.mNumMeshes = static_cast<unsigned int>(meshes.size()); + parent->mMeshes = new unsigned int[meshes.size()](); + parent->mNumMeshes = static_cast<unsigned int>(meshes.size()); - std::swap_ranges(meshes.begin(), meshes.end(), nd.mMeshes); + std::swap_ranges(meshes.begin(), meshes.end(), parent->mMeshes); } } - std::vector<unsigned int> FBXConverter::ConvertMesh(const MeshGeometry& mesh, const Model& model, - const aiMatrix4x4& node_global_transform, aiNode& nd) + 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; @@ -961,18 +990,18 @@ namespace Assimp { const MatIndexArray::value_type base = mindices[0]; for (MatIndexArray::value_type index : mindices) { if (index != base) { - return ConvertMeshMultiMaterial(mesh, model, node_global_transform, nd); + return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform); } } } // faster code-path, just copy the data - temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform, nd)); + 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, - const aiMatrix4x4& node_global_transform, aiNode& nd) + aiNode *parent, aiNode *root_node) { std::vector<unsigned int> temp; @@ -983,7 +1012,7 @@ namespace Assimp { return temp; } - aiMesh* const out_mesh = SetupEmptyMesh(line, nd); + aiMesh* const out_mesh = SetupEmptyMesh(line, root_node); out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; // copy vertices @@ -1018,7 +1047,7 @@ namespace Assimp { return temp; } - aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd) + aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode *parent) { aiMesh* const out_mesh = new aiMesh(); meshes.push_back(out_mesh); @@ -1035,17 +1064,18 @@ namespace Assimp { } else { - out_mesh->mName = nd.mName; + out_mesh->mName = parent->mName; } return out_mesh; } - unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, - const aiMatrix4x4& node_global_transform, aiNode& nd) + 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, nd); + aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent); const std::vector<aiVector3D>& vertices = mesh.GetVertices(); const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); @@ -1112,7 +1142,7 @@ namespace Assimp { binormals = &tempBinormals; } else { - binormals = NULL; + binormals = nullptr; } } @@ -1162,8 +1192,9 @@ namespace Assimp { ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]); } - if (doc.Settings().readWeights && mesh.DeformerSkin() != NULL) { - ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION); + 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; @@ -1208,8 +1239,10 @@ namespace Assimp { return static_cast<unsigned int>(meshes.size() - 1); } - std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, - const aiMatrix4x4& node_global_transform, aiNode& nd) + 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()); @@ -1220,7 +1253,7 @@ namespace Assimp { for (MatIndexArray::value_type index : mindices) { if (had.find(index) == had.end()) { - indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform, nd)); + indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform)); had.insert(index); } } @@ -1228,18 +1261,18 @@ namespace Assimp { return indices; } - unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, - MatIndexArray::value_type index, - const aiMatrix4x4& node_global_transform, - aiNode& nd) + 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, nd); + 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() != NULL; + const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != nullptr; unsigned int count_faces = 0; unsigned int count_vertices = 0; @@ -1299,7 +1332,7 @@ namespace Assimp { binormals = &tempBinormals; } else { - binormals = NULL; + binormals = nullptr; } } @@ -1398,7 +1431,7 @@ namespace Assimp { ConvertMaterialForMesh(out_mesh, model, mesh, index); if (process_weights) { - ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping); + ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, index, &reverseMapping); } std::vector<aiAnimMesh*> animMeshes; @@ -1448,10 +1481,10 @@ namespace Assimp { return static_cast<unsigned int>(meshes.size() - 1); } - void FBXConverter::ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo, - const aiMatrix4x4& node_global_transform, - unsigned int materialIndex, - std::vector<unsigned int>* outputVertStartIndices) + 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()); @@ -1462,13 +1495,12 @@ namespace Assimp { const Skin& sk = *geo.DeformerSkin(); std::vector<aiBone*> bones; - bones.reserve(sk.Clusters().size()); 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); @@ -1482,15 +1514,16 @@ namespace Assimp { 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 NULL if index is out of bounds + // ToOutputVertexIndex only returns nullptr if index is out of bounds // which should never happen - ai_assert(out_idx != NULL); + ai_assert(out_idx != nullptr); index_out_indices.push_back(no_index_sentinel); count_out_indices.push_back(0); @@ -1519,68 +1552,107 @@ namespace Assimp { } } } - + // 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, model, *cluster, out_indices, index_out_indices, - count_out_indices, node_global_transform); + ConvertCluster(bones, cluster, out_indices, index_out_indices, + count_out_indices, absolute_transform, parent, root_node); } + + bone_map.clear(); } - catch (std::exception&) { + 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; - } - - out->mBones = new aiBone*[bones.size()](); - out->mNumBones = static_cast<unsigned int>(bones.size()); + } else { + out->mBones = new aiBone *[bones.size()](); + out->mNumBones = static_cast<unsigned int>(bones.size()); - std::swap_ranges(bones.begin(), bones.end(), out->mBones); + std::swap_ranges(bones.begin(), bones.end(), out->mBones); + } } - void FBXConverter::ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, 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& node_global_transform) + const aiNode* FBXConverter::GetNodeByName( const aiString& name, aiNode *current_node ) { + aiNode * iter = current_node; + //printf("Child count: %d", iter->mNumChildren); + return iter; + } - aiBone* const bone = new aiBone(); - bones.push_back(bone); + 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)); - bone->mName = FixNodeName(cl.TargetNode()->Name()); + aiBone *bone = nullptr; - bone->mOffsetMatrix = cl.TransformLink(); - bone->mOffsetMatrix.Inverse(); + 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; - bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform; + // store local transform link for post processing + bone->mOffsetMatrix = cl->TransformLink(); + bone->mOffsetMatrix.Inverse(); - bone->mNumWeights = static_cast<unsigned int>(out_indices.size()); - aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()]; + aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform; - const size_t no_index_sentinel = std::numeric_limits<size_t>::max(); - const WeightArray& weights = cl.GetWeights(); + bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset - 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; - } + // + // 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 cc = count_out_indices[i]; - for (size_t j = 0; j < cc; ++j) { - aiVertexWeight& out_weight = *cursor++; + const size_t no_index_sentinel = std::numeric_limits<size_t>::max(); + const WeightArray& weights = cl->GetWeights(); - out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]); - out_weight.mWeight = weights[i]; + 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, @@ -1710,7 +1782,7 @@ namespace Assimp { 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); + VideoMap::const_iterator it = textures_converted.find(*media); if (it != textures_converted.end()) { index = (*it).second; textureReady = true; @@ -1718,7 +1790,7 @@ namespace Assimp { else { if (media->ContentLength() > 0) { index = ConvertVideo(*media); - textures_converted[media] = index; + textures_converted[*media] = index; textureReady = true; } } @@ -2242,13 +2314,13 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa if (media != nullptr && media->ContentLength() > 0) { unsigned int index; - VideoMap::const_iterator it = textures_converted.find(media); + VideoMap::const_iterator it = textures_converted.find(*media); if (it != textures_converted.end()) { index = (*it).second; } else { index = ConvertVideo(*media); - textures_converted[media] = index; + textures_converted[*media] = index; } // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) @@ -2676,7 +2748,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa // sanity check whether the input is ok static void validateAnimCurveNodes(const std::vector<const AnimationCurveNode*>& curves, bool strictMode) { - const Object* target(NULL); + const Object* target(nullptr); for (const AnimationCurveNode* node : curves) { if (!target) { target = node->Target(); @@ -2707,7 +2779,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa #ifdef ASSIMP_BUILD_DEBUG validateAnimCurveNodes(curves, doc.Settings().strictMode); #endif - const AnimationCurveNode* curve_node = NULL; + const AnimationCurveNode* curve_node = nullptr; for (const AnimationCurveNode* node : curves) { ai_assert(node); @@ -2967,7 +3039,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa TransformationCompDefaultValue(comp) ); - const float epsilon = 1e-6f; + const float epsilon = Math::getEpsilon<float>(); return (dyn_val - static_val).SquareLength() < epsilon; } @@ -3555,7 +3627,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa ai_assert(!out->mMeshes); ai_assert(!out->mNumMeshes); - // note: the trailing () ensures initialization with NULL - not + // 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. @@ -3602,6 +3674,47 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa } } + 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) { diff --git a/thirdparty/assimp/code/FBX/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h index ab610058a4..46693bdca6 100644 --- a/thirdparty/assimp/code/FBX/FBXConverter.h +++ b/thirdparty/assimp/code/FBX/FBXConverter.h @@ -76,16 +76,6 @@ namespace Assimp { namespace FBX { class Document; - -enum class FbxUnit { - cm = 0, - m, - km, - NumUnits, - - Undefined -}; - /** * Convert a FBX #Document to #aiScene * @param out Empty scene to be populated @@ -133,7 +123,7 @@ private: // ------------------------------------------------------------------------------------------------ // collect and assign child nodes - void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4()); + void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node); // ------------------------------------------------------------------------------------------------ void ConvertLights(const Model& model, const std::string &orig_name ); @@ -189,32 +179,35 @@ private: void SetupNodeMetadata(const Model& model, aiNode& nd); // ------------------------------------------------------------------------------------------------ - void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform); + 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, - const aiMatrix4x4& node_global_transform, aiNode& nd); + 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, - const aiMatrix4x4& node_global_transform, aiNode& nd); + aiNode *parent, aiNode *root_node); // ------------------------------------------------------------------------------------------------ - aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode& nd); + aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent); // ------------------------------------------------------------------------------------------------ - unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, - const aiMatrix4x4& node_global_transform, aiNode& nd); + 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, - const aiMatrix4x4& node_global_transform, aiNode& nd); + 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, - const aiMatrix4x4& node_global_transform, aiNode& nd); + 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() */ @@ -227,17 +220,17 @@ private: * - 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& node_global_transform = aiMatrix4x4(), - unsigned int materialIndex = NO_MATERIAL_SEPARATION, - std::vector<unsigned int>* outputVertStartIndices = NULL); - + 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*>& bones, const Model& /*model*/, 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& node_global_transform); + 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, @@ -434,6 +427,10 @@ private: // 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; @@ -445,28 +442,47 @@ private: std::vector<aiCamera*> cameras; std::vector<aiTexture*> textures; - using MaterialMap = std::map<const Material*, unsigned int>; + using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>; MaterialMap materials_converted; - using VideoMap = std::map<const Video*, unsigned int>; + using VideoMap = std::fbx_unordered_map<const Video, unsigned int>; VideoMap textures_converted; - using MeshMap = std::map<const Geometry*, std::vector<unsigned int> >; + 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::map<std::string, unsigned int> ; + 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::unordered_map<std::string, unsigned int>; + 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; - FbxUnit mCurrentUnit; + + 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); }; } diff --git a/thirdparty/assimp/code/FBX/FBXDocument.h b/thirdparty/assimp/code/FBX/FBXDocument.h index 18e5c38f13..a60d7d9efa 100644 --- a/thirdparty/assimp/code/FBX/FBXDocument.h +++ b/thirdparty/assimp/code/FBX/FBXDocument.h @@ -637,6 +637,20 @@ public: 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; @@ -1005,10 +1019,10 @@ public: // 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::map<uint64_t, LazyObject*> ObjectMap; +typedef std::fbx_unordered_map<uint64_t, LazyObject*> ObjectMap; typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap; -typedef std::multimap<uint64_t, const Connection*> ConnectionMap; +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(). */ @@ -1177,4 +1191,25 @@ private: } // 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/FBXExportProperty.cpp b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp index f8593e6295..f2a63b72b9 100644 --- a/thirdparty/assimp/code/FBX/FBXExportProperty.cpp +++ b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp @@ -59,11 +59,7 @@ namespace FBX { FBXExportProperty::FBXExportProperty(bool v) : type('C') -, data(1) { - data = { - uint8_t(v) - }; -} +, data(1, uint8_t(v)) {} FBXExportProperty::FBXExportProperty(int16_t v) : type('Y') diff --git a/thirdparty/assimp/code/FBX/FBXExporter.cpp b/thirdparty/assimp/code/FBX/FBXExporter.cpp index 8ebc8555a2..9316dc4f02 100644 --- a/thirdparty/assimp/code/FBX/FBXExporter.cpp +++ b/thirdparty/assimp/code/FBX/FBXExporter.cpp @@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <vector> #include <array> #include <unordered_set> +#include <numeric> // RESOURCES: // https://code.blender.org/2013/08/fbx-binary-file-format-specification/ @@ -1005,6 +1006,9 @@ void FBXExporter::WriteObjects () 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; @@ -1031,21 +1035,35 @@ void FBXExporter::WriteObjects () 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; - 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)); + 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 ); @@ -1116,6 +1134,51 @@ void FBXExporter::WriteObjects () 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) { @@ -1209,6 +1272,11 @@ void FBXExporter::WriteObjects () 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)); @@ -1221,7 +1289,7 @@ void FBXExporter::WriteObjects () for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr) { - FBX::Node layerExtra("Layer", int32_t(1)); + FBX::Node layerExtra("Layer", int32_t(lr)); layerExtra.AddChild("Version", int32_t(100)); FBX::Node leExtra("LayerElement"); leExtra.AddChild("Type", "LayerElementUV"); @@ -1748,28 +1816,8 @@ void FBXExporter::WriteObjects () // connect it connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]); - // we will be indexing by vertex... - // but there might be a different number of "vertices" - // between assimp and our output FBX. - // this code is cut-and-pasted from the geometry section above... - // ideally this should not be so. - // --- - // 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; - 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; - ++index; - } else { - vertex_indices.push_back(int32_t(elem->second)); - } - } + //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. @@ -2435,7 +2483,7 @@ void FBXExporter::WriteModelNodes( void FBXExporter::WriteAnimationCurveNode( StreamWriterLE& outstream, int64_t uid, - std::string name, // "T", "R", or "S" + const std::string& name, // "T", "R", or "S" aiVector3D default_value, std::string property_name, // "Lcl Translation" etc int64_t layer_uid, diff --git a/thirdparty/assimp/code/FBX/FBXExporter.h b/thirdparty/assimp/code/FBX/FBXExporter.h index 71fb55c57f..1ae727eda9 100644 --- a/thirdparty/assimp/code/FBX/FBXExporter.h +++ b/thirdparty/assimp/code/FBX/FBXExporter.h @@ -156,7 +156,7 @@ namespace Assimp void WriteAnimationCurveNode( StreamWriterLE& outstream, int64_t uid, - std::string name, // "T", "R", or "S" + const std::string& name, // "T", "R", or "S" aiVector3D default_value, std::string property_name, // "Lcl Translation" etc int64_t animation_layer_uid, diff --git a/thirdparty/assimp/code/FBX/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp index 271935a568..afcc1ddc78 100644 --- a/thirdparty/assimp/code/FBX/FBXImporter.cpp +++ b/thirdparty/assimp/code/FBX/FBXImporter.cpp @@ -48,26 +48,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXImporter.h" -#include "FBXTokenizer.h" +#include "FBXConverter.h" +#include "FBXDocument.h" #include "FBXParser.h" +#include "FBXTokenizer.h" #include "FBXUtil.h" -#include "FBXDocument.h" -#include "FBXConverter.h" -#include <assimp/StreamReader.h> #include <assimp/MemoryIOWrapper.h> -#include <assimp/Importer.hpp> +#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; +template <> +const char *LogFunctions<FBXImporter>::Prefix() { + static auto prefix = "FBX: "; + return prefix; } -} +} // namespace Assimp using namespace Assimp; using namespace Assimp::Formatter; @@ -76,136 +76,123 @@ using namespace Assimp::FBX; namespace { static const aiImporterDesc desc = { - "Autodesk FBX Importer", - "", - "", - "", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "fbx" + "Autodesk FBX Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "fbx" }; } // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by #Importer -FBXImporter::FBXImporter() -{ +FBXImporter::FBXImporter() { } // ------------------------------------------------------------------------------------------------ // Destructor, private as well -FBXImporter::~FBXImporter() -{ +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; +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; +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); +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); - - FbxUnit unit(FbxUnit::cm); - if (settings.convertToMeters) { - unit = FbxUnit::m; - } - - // 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; - } +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/FBXMeshGeometry.cpp b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp index 5c9a0e309d..1386e2383c 100644 --- a/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp +++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp @@ -610,11 +610,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons const std::string& ReferenceInformationType) { const size_t face_count = m_faces.size(); - if(face_count <= 0) + 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. @@ -625,16 +625,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons if (materials_out.empty()) { FBXImporter::LogError(Formatter::format("expected material index, ignoring")); return; - } - else if (materials_out.size() > 1) { + } 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") { + } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") { materials_out.resize(face_count); if(materials_out.size() != face_count) { @@ -643,18 +641,16 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons ); return; } - } - else { + } 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 (!sc) { +: 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); diff --git a/thirdparty/assimp/code/MMD/MMDCpp14.h b/thirdparty/assimp/code/MMD/MMDCpp14.h deleted file mode 100644 index 638b0bfd2f..0000000000 --- a/thirdparty/assimp/code/MMD/MMDCpp14.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. - ----------------------------------------------------------------------- -*/ -#pragma once - -#ifndef MMD_CPP14_H -#define MMD_CPP14_H - -#include <cstddef> -#include <memory> -#include <type_traits> -#include <utility> - -namespace mmd { - template<class T> struct _Unique_if { - typedef std::unique_ptr<T> _Single_object; - }; - - template<class T> struct _Unique_if<T[]> { - typedef std::unique_ptr<T[]> _Unknown_bound; - }; - - template<class T, size_t N> struct _Unique_if<T[N]> { - typedef void _Known_bound; - }; - - template<class T, class... Args> - typename _Unique_if<T>::_Single_object - make_unique(Args&&... args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - } - - template<class T> - typename _Unique_if<T>::_Unknown_bound - make_unique(size_t n) { - typedef typename std::remove_extent<T>::type U; - return std::unique_ptr<T>(new U[n]()); - } - - template<class T, class... Args> - typename _Unique_if<T>::_Known_bound - make_unique(Args&&...) = delete; -} - -#endif diff --git a/thirdparty/assimp/code/MMD/MMDImporter.cpp b/thirdparty/assimp/code/MMD/MMDImporter.cpp deleted file mode 100644 index e7744e4cd0..0000000000 --- a/thirdparty/assimp/code/MMD/MMDImporter.cpp +++ /dev/null @@ -1,372 +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. ---------------------------------------------------------------------------- -*/ - -#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER - -#include "MMD/MMDImporter.h" -#include "MMD/MMDPmdParser.h" -#include "MMD/MMDPmxParser.h" -#include "MMD/MMDVmdParser.h" -#include "PostProcessing/ConvertToLHProcess.h" - -#include <assimp/DefaultIOSystem.h> -#include <assimp/Importer.hpp> -#include <assimp/ai_assert.h> -#include <assimp/scene.h> - -#include <fstream> -#include <iomanip> -#include <memory> - -static const aiImporterDesc desc = {"MMD Importer", - "", - "", - "surfaces supported?", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "pmx"}; - -namespace Assimp { - -using namespace std; - -// ------------------------------------------------------------------------------------------------ -// Default constructor -MMDImporter::MMDImporter() -: m_Buffer() -, m_strAbsPath("") { - DefaultIOSystem io; - m_strAbsPath = io.getOsSeparator(); -} - -// ------------------------------------------------------------------------------------------------ -// Destructor. -MMDImporter::~MMDImporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Returns true, if file is an pmx file. -bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, - bool checkSig) const { - if (!checkSig) // Check File Extension - { - return SimpleExtensionCheck(pFile, "pmx"); - } else // Check file Header - { - static const char *pTokens[] = {"PMX "}; - return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1); - } -} - -// ------------------------------------------------------------------------------------------------ -const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; } - -// ------------------------------------------------------------------------------------------------ -// MMD import implementation -void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene, - IOSystem * /*pIOHandler*/) { - // Read file by istream - std::filebuf fb; - if (!fb.open(file, std::ios::in | std::ios::binary)) { - throw DeadlyImportError("Failed to open file " + file + "."); - } - - std::istream fileStream(&fb); - - // Get the file-size and validate it, throwing an exception when fails - fileStream.seekg(0, fileStream.end); - size_t fileSize = static_cast<size_t>(fileStream.tellg()); - fileStream.seekg(0, fileStream.beg); - - if (fileSize < sizeof(pmx::PmxModel)) { - throw DeadlyImportError(file + " is too small."); - } - - pmx::PmxModel model; - model.Read(&fileStream); - - CreateDataFromImport(&model, pScene); -} - -// ------------------------------------------------------------------------------------------------ -void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel, - aiScene *pScene) { - if (pModel == NULL) { - return; - } - - aiNode *pNode = new aiNode; - if (!pModel->model_name.empty()) { - pNode->mName.Set(pModel->model_name); - } - - pScene->mRootNode = pNode; - - pNode = new aiNode; - pScene->mRootNode->addChildren(1, &pNode); - pNode->mName.Set(string(pModel->model_name) + string("_mesh")); - - // split mesh by materials - pNode->mNumMeshes = pModel->material_count; - pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; - for (unsigned int index = 0; index < pNode->mNumMeshes; index++) { - pNode->mMeshes[index] = index; - } - - pScene->mNumMeshes = pModel->material_count; - pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; - for (unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++) { - const int indexCount = pModel->materials[i].index_count; - - pScene->mMeshes[i] = CreateMesh(pModel, indexStart, indexCount); - pScene->mMeshes[i]->mName = pModel->materials[i].material_name; - pScene->mMeshes[i]->mMaterialIndex = i; - indexStart += indexCount; - } - - // create node hierarchy for bone position - std::unique_ptr<aiNode *[]> ppNode(new aiNode *[pModel->bone_count]); - for (auto i = 0; i < pModel->bone_count; i++) { - ppNode[i] = new aiNode(pModel->bones[i].bone_name); - } - - for (auto i = 0; i < pModel->bone_count; i++) { - const pmx::PmxBone &bone = pModel->bones[i]; - - if (bone.parent_index < 0) { - pScene->mRootNode->addChildren(1, ppNode.get() + i); - } else { - ppNode[bone.parent_index]->addChildren(1, ppNode.get() + i); - - aiVector3D v3 = aiVector3D( - bone.position[0] - pModel->bones[bone.parent_index].position[0], - bone.position[1] - pModel->bones[bone.parent_index].position[1], - bone.position[2] - pModel->bones[bone.parent_index].position[2]); - aiMatrix4x4::Translation(v3, ppNode[i]->mTransformation); - } - } - - // create materials - pScene->mNumMaterials = pModel->material_count; - pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; - for (unsigned int i = 0; i < pScene->mNumMaterials; i++) { - pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel); - } - - // Convert everything to OpenGL space - MakeLeftHandedProcess convertProcess; - convertProcess.Execute(pScene); - - FlipUVsProcess uvFlipper; - uvFlipper.Execute(pScene); - - FlipWindingOrderProcess windingFlipper; - windingFlipper.Execute(pScene); -} - -// ------------------------------------------------------------------------------------------------ -aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel, - const int indexStart, const int indexCount) { - aiMesh *pMesh = new aiMesh; - - pMesh->mNumVertices = indexCount; - - pMesh->mNumFaces = indexCount / 3; - pMesh->mFaces = new aiFace[pMesh->mNumFaces]; - - const int numIndices = 3; // triangular face - for (unsigned int index = 0; index < pMesh->mNumFaces; index++) { - pMesh->mFaces[index].mNumIndices = numIndices; - unsigned int *indices = new unsigned int[numIndices]; - indices[0] = numIndices * index; - indices[1] = numIndices * index + 1; - indices[2] = numIndices * index + 2; - pMesh->mFaces[index].mIndices = indices; - } - - pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; - pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices]; - pMesh->mNumUVComponents[0] = 2; - - // additional UVs - for (int i = 1; i <= pModel->setting.uv; i++) { - pMesh->mTextureCoords[i] = new aiVector3D[pMesh->mNumVertices]; - pMesh->mNumUVComponents[i] = 4; - } - - map<int, vector<aiVertexWeight>> bone_vertex_map; - - // fill in contents and create bones - for (int index = 0; index < indexCount; index++) { - const pmx::PmxVertex *v = - &pModel->vertices[pModel->indices[indexStart + index]]; - const float *position = v->position; - pMesh->mVertices[index].Set(position[0], position[1], position[2]); - const float *normal = v->normal; - - pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]); - pMesh->mTextureCoords[0][index].x = v->uv[0]; - pMesh->mTextureCoords[0][index].y = v->uv[1]; - - for (int i = 1; i <= pModel->setting.uv; i++) { - // TODO: wrong here? use quaternion transform? - pMesh->mTextureCoords[i][index].x = v->uva[i][0]; - pMesh->mTextureCoords[i][index].y = v->uva[i][1]; - } - - // handle bone map - const auto vsBDEF1_ptr = - dynamic_cast<pmx::PmxVertexSkinningBDEF1 *>(v->skinning.get()); - const auto vsBDEF2_ptr = - dynamic_cast<pmx::PmxVertexSkinningBDEF2 *>(v->skinning.get()); - const auto vsBDEF4_ptr = - dynamic_cast<pmx::PmxVertexSkinningBDEF4 *>(v->skinning.get()); - const auto vsSDEF_ptr = - dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get()); - switch (v->skinning_type) { - case pmx::PmxVertexSkinningType::BDEF1: - bone_vertex_map[vsBDEF1_ptr->bone_index].push_back( - aiVertexWeight(index, 1.0)); - break; - case pmx::PmxVertexSkinningType::BDEF2: - bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back( - aiVertexWeight(index, vsBDEF2_ptr->bone_weight)); - bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back( - aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight)); - break; - case pmx::PmxVertexSkinningType::BDEF4: - bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back( - aiVertexWeight(index, vsBDEF4_ptr->bone_weight1)); - bone_vertex_map[vsBDEF4_ptr->bone_index2].push_back( - aiVertexWeight(index, vsBDEF4_ptr->bone_weight2)); - bone_vertex_map[vsBDEF4_ptr->bone_index3].push_back( - aiVertexWeight(index, vsBDEF4_ptr->bone_weight3)); - bone_vertex_map[vsBDEF4_ptr->bone_index4].push_back( - aiVertexWeight(index, vsBDEF4_ptr->bone_weight4)); - break; - case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0, - // sdef_r1? - bone_vertex_map[vsSDEF_ptr->bone_index1].push_back( - aiVertexWeight(index, vsSDEF_ptr->bone_weight)); - bone_vertex_map[vsSDEF_ptr->bone_index2].push_back( - aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight)); - break; - case pmx::PmxVertexSkinningType::QDEF: - const auto vsQDEF_ptr = - dynamic_cast<pmx::PmxVertexSkinningQDEF *>(v->skinning.get()); - bone_vertex_map[vsQDEF_ptr->bone_index1].push_back( - aiVertexWeight(index, vsQDEF_ptr->bone_weight1)); - bone_vertex_map[vsQDEF_ptr->bone_index2].push_back( - aiVertexWeight(index, vsQDEF_ptr->bone_weight2)); - bone_vertex_map[vsQDEF_ptr->bone_index3].push_back( - aiVertexWeight(index, vsQDEF_ptr->bone_weight3)); - bone_vertex_map[vsQDEF_ptr->bone_index4].push_back( - aiVertexWeight(index, vsQDEF_ptr->bone_weight4)); - break; - } - } - - // make all bones for each mesh - // assign bone weights to skinned bones (otherwise just initialize) - auto bone_ptr_ptr = new aiBone *[pModel->bone_count]; - pMesh->mNumBones = pModel->bone_count; - pMesh->mBones = bone_ptr_ptr; - for (auto ii = 0; ii < pModel->bone_count; ++ii) { - auto pBone = new aiBone; - const auto &pmxBone = pModel->bones[ii]; - pBone->mName = pmxBone.bone_name; - aiVector3D pos(pmxBone.position[0], pmxBone.position[1], pmxBone.position[2]); - aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix); - auto it = bone_vertex_map.find(ii); - if (it != bone_vertex_map.end()) { - pBone->mNumWeights = static_cast<unsigned int>(it->second.size()); - pBone->mWeights = new aiVertexWeight[pBone->mNumWeights]; - for (unsigned int j = 0; j < pBone->mNumWeights; j++) { - pBone->mWeights[j] = it->second[j]; - } - } - bone_ptr_ptr[ii] = pBone; - } - - return pMesh; -} - -// ------------------------------------------------------------------------------------------------ -aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat, - const pmx::PmxModel *pModel) { - aiMaterial *mat = new aiMaterial(); - aiString name(pMat->material_english_name); - mat->AddProperty(&name, AI_MATKEY_NAME); - - aiColor3D diffuse(pMat->diffuse[0], pMat->diffuse[1], pMat->diffuse[2]); - mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - aiColor3D specular(pMat->specular[0], pMat->specular[1], pMat->specular[2]); - mat->AddProperty(&specular, 1, AI_MATKEY_COLOR_SPECULAR); - aiColor3D ambient(pMat->ambient[0], pMat->ambient[1], pMat->ambient[2]); - mat->AddProperty(&ambient, 1, AI_MATKEY_COLOR_AMBIENT); - - float opacity = pMat->diffuse[3]; - mat->AddProperty(&opacity, 1, AI_MATKEY_OPACITY); - float shininess = pMat->specularlity; - mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH); - - if(pMat->diffuse_texture_index >= 0) { - aiString texture_path(pModel->textures[pMat->diffuse_texture_index]); - mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); - } - - int mapping_uvwsrc = 0; - mat->AddProperty(&mapping_uvwsrc, 1, - AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0)); - - return mat; -} - -// ------------------------------------------------------------------------------------------------ - -} // Namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_MMD_IMPORTER diff --git a/thirdparty/assimp/code/MMD/MMDImporter.h b/thirdparty/assimp/code/MMD/MMDImporter.h deleted file mode 100644 index 4ee94eeb00..0000000000 --- a/thirdparty/assimp/code/MMD/MMDImporter.h +++ /dev/null @@ -1,96 +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. - ----------------------------------------------------------------------- -*/ -#ifndef MMD_FILE_IMPORTER_H_INC -#define MMD_FILE_IMPORTER_H_INC - -#include <assimp/BaseImporter.h> -#include "MMDPmxParser.h" -#include <assimp/material.h> -#include <vector> - -struct aiMesh; - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -/// \class MMDImporter -/// \brief Imports MMD a pmx/pmd/vmd file -// ------------------------------------------------------------------------------------------------ -class MMDImporter : public BaseImporter { -public: - /// \brief Default constructor - MMDImporter(); - - /// \brief Destructor - ~MMDImporter(); - -public: - /// \brief Returns whether the class can handle the format of the given file. - /// \remark See BaseImporter::CanRead() for details. - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; - -private: - //! \brief Appends the supported extension. - const aiImporterDesc* GetInfo () const; - - //! \brief File import implementation. - void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); - - //! \brief Create the data from imported content. - void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene); - - //! \brief Create the mesh - aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount); - - //! \brief Create the material - aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel); - -private: - //! Data buffer - std::vector<char> m_Buffer; - //! Absolute pathname of model in file system - std::string m_strAbsPath; -}; - -// ------------------------------------------------------------------------------------------------ - -} // Namespace Assimp - -#endif
\ No newline at end of file diff --git a/thirdparty/assimp/code/MMD/MMDPmdParser.h b/thirdparty/assimp/code/MMD/MMDPmdParser.h deleted file mode 100644 index d2f2224aa1..0000000000 --- a/thirdparty/assimp/code/MMD/MMDPmdParser.h +++ /dev/null @@ -1,597 +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 <vector> -#include <string> -#include <memory> -#include <iostream> -#include <fstream> -#include "MMDCpp14.h" - -namespace pmd -{ - class PmdHeader - { - public: - std::string name; - std::string name_english; - std::string comment; - std::string comment_english; - - bool Read(std::ifstream* stream) - { - char buffer[256]; - stream->read(buffer, 20); - name = std::string(buffer); - stream->read(buffer, 256); - comment = std::string(buffer); - return true; - } - - bool ReadExtension(std::ifstream* stream) - { - char buffer[256]; - stream->read(buffer, 20); - name_english = std::string(buffer); - stream->read(buffer, 256); - comment_english = std::string(buffer); - return true; - } - }; - - class PmdVertex - { - public: - float position[3]; - - float normal[3]; - - float uv[2]; - - uint16_t bone_index[2]; - - uint8_t bone_weight; - - bool edge_invisible; - - bool Read(std::ifstream* stream) - { - stream->read((char*) position, sizeof(float) * 3); - stream->read((char*) normal, sizeof(float) * 3); - stream->read((char*) uv, sizeof(float) * 2); - stream->read((char*) bone_index, sizeof(uint16_t) * 2); - stream->read((char*) &bone_weight, sizeof(uint8_t)); - stream->read((char*) &edge_invisible, sizeof(uint8_t)); - return true; - } - }; - - class PmdMaterial - { - public: - float diffuse[4]; - float power; - float specular[3]; - float ambient[3]; - uint8_t toon_index; - uint8_t edge_flag; - uint32_t index_count; - std::string texture_filename; - std::string sphere_filename; - - bool Read(std::ifstream* stream) - { - char buffer[20]; - stream->read((char*) &diffuse, sizeof(float) * 4); - stream->read((char*) &power, sizeof(float)); - stream->read((char*) &specular, sizeof(float) * 3); - stream->read((char*) &ambient, sizeof(float) * 3); - stream->read((char*) &toon_index, sizeof(uint8_t)); - stream->read((char*) &edge_flag, sizeof(uint8_t)); - stream->read((char*) &index_count, sizeof(uint32_t)); - stream->read((char*) &buffer, sizeof(char) * 20); - char* pstar = strchr(buffer, '*'); - if (NULL == pstar) - { - texture_filename = std::string(buffer); - sphere_filename.clear(); - } - else { - *pstar = 0; - texture_filename = std::string(buffer); - sphere_filename = std::string(pstar+1); - } - return true; - } - }; - - enum class BoneType : uint8_t - { - Rotation, - RotationAndMove, - IkEffector, - Unknown, - IkEffectable, - RotationEffectable, - IkTarget, - Invisible, - Twist, - RotationMovement - }; - - class PmdBone - { - public: - std::string name; - std::string name_english; - uint16_t parent_bone_index; - uint16_t tail_pos_bone_index; - BoneType bone_type; - uint16_t ik_parent_bone_index; - float bone_head_pos[3]; - - void Read(std::istream *stream) - { - char buffer[20]; - stream->read(buffer, 20); - name = std::string(buffer); - stream->read((char*) &parent_bone_index, sizeof(uint16_t)); - stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t)); - stream->read((char*) &bone_type, sizeof(uint8_t)); - stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t)); - stream->read((char*) &bone_head_pos, sizeof(float) * 3); - } - - void ReadExpantion(std::istream *stream) - { - char buffer[20]; - stream->read(buffer, 20); - name_english = std::string(buffer); - } - }; - - class PmdIk - { - public: - uint16_t ik_bone_index; - uint16_t target_bone_index; - uint16_t interations; - float angle_limit; - std::vector<uint16_t> ik_child_bone_index; - - void Read(std::istream *stream) - { - stream->read((char *) &ik_bone_index, sizeof(uint16_t)); - stream->read((char *) &target_bone_index, sizeof(uint16_t)); - uint8_t ik_chain_length; - stream->read((char*) &ik_chain_length, sizeof(uint8_t)); - stream->read((char *) &interations, sizeof(uint16_t)); - stream->read((char *) &angle_limit, sizeof(float)); - ik_child_bone_index.resize(ik_chain_length); - for (int i = 0; i < ik_chain_length; i++) - { - stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t)); - } - } - }; - - class PmdFaceVertex - { - public: - int vertex_index; - float position[3]; - - void Read(std::istream *stream) - { - stream->read((char *) &vertex_index, sizeof(int)); - stream->read((char *) position, sizeof(float) * 3); - } - }; - - enum class FaceCategory : uint8_t - { - Base, - Eyebrow, - Eye, - Mouth, - Other - }; - - class PmdFace - { - public: - std::string name; - FaceCategory type; - std::vector<PmdFaceVertex> vertices; - std::string name_english; - - void Read(std::istream *stream) - { - char buffer[20]; - stream->read(buffer, 20); - name = std::string(buffer); - int vertex_count; - stream->read((char*) &vertex_count, sizeof(int)); - stream->read((char*) &type, sizeof(uint8_t)); - vertices.resize(vertex_count); - for (int i = 0; i < vertex_count; i++) - { - vertices[i].Read(stream); - } - } - - void ReadExpantion(std::istream *stream) - { - char buffer[20]; - stream->read(buffer, 20); - name_english = std::string(buffer); - } - }; - - class PmdBoneDispName - { - public: - std::string bone_disp_name; - std::string bone_disp_name_english; - - void Read(std::istream *stream) - { - char buffer[50]; - stream->read(buffer, 50); - bone_disp_name = std::string(buffer); - bone_disp_name_english.clear(); - } - void ReadExpantion(std::istream *stream) - { - char buffer[50]; - stream->read(buffer, 50); - bone_disp_name_english = std::string(buffer); - } - }; - - class PmdBoneDisp - { - public: - uint16_t bone_index; - uint8_t bone_disp_index; - - void Read(std::istream *stream) - { - stream->read((char*) &bone_index, sizeof(uint16_t)); - stream->read((char*) &bone_disp_index, sizeof(uint8_t)); - } - }; - - enum class RigidBodyShape : uint8_t - { - Sphere = 0, - Box = 1, - Cpusel = 2 - }; - - enum class RigidBodyType : uint8_t - { - BoneConnected = 0, - Physics = 1, - ConnectedPhysics = 2 - }; - - class PmdRigidBody - { - public: - std::string name; - uint16_t related_bone_index; - uint8_t group_index; - uint16_t mask; - RigidBodyShape shape; - float size[3]; - float position[3]; - float orientation[3]; - float weight; - float linear_damping; - float anglar_damping; - float restitution; - float friction; - RigidBodyType rigid_type; - - void Read(std::istream *stream) - { - char buffer[20]; - stream->read(buffer, sizeof(char) * 20); - name = (std::string(buffer)); - stream->read((char*) &related_bone_index, sizeof(uint16_t)); - stream->read((char*) &group_index, sizeof(uint8_t)); - stream->read((char*) &mask, sizeof(uint16_t)); - stream->read((char*) &shape, sizeof(uint8_t)); - stream->read((char*) size, sizeof(float) * 3); - stream->read((char*) position, sizeof(float) * 3); - stream->read((char*) orientation, sizeof(float) * 3); - stream->read((char*) &weight, sizeof(float)); - stream->read((char*) &linear_damping, sizeof(float)); - stream->read((char*) &anglar_damping, sizeof(float)); - stream->read((char*) &restitution, sizeof(float)); - stream->read((char*) &friction, sizeof(float)); - stream->read((char*) &rigid_type, sizeof(char)); - } - }; - - class PmdConstraint - { - public: - std::string name; - uint32_t rigid_body_index_a; - uint32_t rigid_body_index_b; - float position[3]; - float orientation[3]; - float linear_lower_limit[3]; - float linear_upper_limit[3]; - float angular_lower_limit[3]; - float angular_upper_limit[3]; - float linear_stiffness[3]; - float angular_stiffness[3]; - - void Read(std::istream *stream) - { - char buffer[20]; - stream->read(buffer, 20); - name = std::string(buffer); - stream->read((char *) &rigid_body_index_a, sizeof(uint32_t)); - stream->read((char *) &rigid_body_index_b, sizeof(uint32_t)); - stream->read((char *) position, sizeof(float) * 3); - stream->read((char *) orientation, sizeof(float) * 3); - stream->read((char *) linear_lower_limit, sizeof(float) * 3); - stream->read((char *) linear_upper_limit, sizeof(float) * 3); - stream->read((char *) angular_lower_limit, sizeof(float) * 3); - stream->read((char *) angular_upper_limit, sizeof(float) * 3); - stream->read((char *) linear_stiffness, sizeof(float) * 3); - stream->read((char *) angular_stiffness, sizeof(float) * 3); - } - }; - - class PmdModel - { - public: - float version; - PmdHeader header; - std::vector<PmdVertex> vertices; - std::vector<uint16_t> indices; - std::vector<PmdMaterial> materials; - std::vector<PmdBone> bones; - std::vector<PmdIk> iks; - std::vector<PmdFace> faces; - std::vector<uint16_t> faces_indices; - std::vector<PmdBoneDispName> bone_disp_name; - std::vector<PmdBoneDisp> bone_disp; - std::vector<std::string> toon_filenames; - std::vector<PmdRigidBody> rigid_bodies; - std::vector<PmdConstraint> constraints; - - static std::unique_ptr<PmdModel> LoadFromFile(const char *filename) - { - std::ifstream stream(filename, std::ios::binary); - if (stream.fail()) - { - std::cerr << "could not open \"" << filename << "\"" << std::endl; - return nullptr; - } - auto result = LoadFromStream(&stream); - stream.close(); - return result; - } - - static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream) - { - auto result = mmd::make_unique<PmdModel>(); - char buffer[100]; - - // magic - char magic[3]; - stream->read(magic, 3); - if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd') - { - std::cerr << "invalid file" << std::endl; - return nullptr; - } - - // version - stream->read((char*) &(result->version), sizeof(float)); - if (result ->version != 1.0f) - { - std::cerr << "invalid version" << std::endl; - return nullptr; - } - - // header - result->header.Read(stream); - - // vertices - uint32_t vertex_num; - stream->read((char*) &vertex_num, sizeof(uint32_t)); - result->vertices.resize(vertex_num); - for (uint32_t i = 0; i < vertex_num; i++) - { - result->vertices[i].Read(stream); - } - - // indices - uint32_t index_num; - stream->read((char*) &index_num, sizeof(uint32_t)); - result->indices.resize(index_num); - for (uint32_t i = 0; i < index_num; i++) - { - stream->read((char*) &result->indices[i], sizeof(uint16_t)); - } - - // materials - uint32_t material_num; - stream->read((char*) &material_num, sizeof(uint32_t)); - result->materials.resize(material_num); - for (uint32_t i = 0; i < material_num; i++) - { - result->materials[i].Read(stream); - } - - // bones - uint16_t bone_num; - stream->read((char*) &bone_num, sizeof(uint16_t)); - result->bones.resize(bone_num); - for (uint32_t i = 0; i < bone_num; i++) - { - result->bones[i].Read(stream); - } - - // iks - uint16_t ik_num; - stream->read((char*) &ik_num, sizeof(uint16_t)); - result->iks.resize(ik_num); - for (uint32_t i = 0; i < ik_num; i++) - { - result->iks[i].Read(stream); - } - - // faces - uint16_t face_num; - stream->read((char*) &face_num, sizeof(uint16_t)); - result->faces.resize(face_num); - for (uint32_t i = 0; i < face_num; i++) - { - result->faces[i].Read(stream); - } - - // face frames - uint8_t face_frame_num; - stream->read((char*) &face_frame_num, sizeof(uint8_t)); - result->faces_indices.resize(face_frame_num); - for (uint32_t i = 0; i < face_frame_num; i++) - { - stream->read((char*) &result->faces_indices[i], sizeof(uint16_t)); - } - - // bone names - uint8_t bone_disp_num; - stream->read((char*) &bone_disp_num, sizeof(uint8_t)); - result->bone_disp_name.resize(bone_disp_num); - for (uint32_t i = 0; i < bone_disp_num; i++) - { - result->bone_disp_name[i].Read(stream); - } - - // bone frame - uint32_t bone_frame_num; - stream->read((char*) &bone_frame_num, sizeof(uint32_t)); - result->bone_disp.resize(bone_frame_num); - for (uint32_t i = 0; i < bone_frame_num; i++) - { - result->bone_disp[i].Read(stream); - } - - // english name - bool english; - stream->read((char*) &english, sizeof(char)); - if (english) - { - result->header.ReadExtension(stream); - for (uint32_t i = 0; i < bone_num; i++) - { - result->bones[i].ReadExpantion(stream); - } - for (uint32_t i = 0; i < face_num; i++) - { - if (result->faces[i].type == pmd::FaceCategory::Base) - { - continue; - } - result->faces[i].ReadExpantion(stream); - } - for (uint32_t i = 0; i < result->bone_disp_name.size(); i++) - { - result->bone_disp_name[i].ReadExpantion(stream); - } - } - - // toon textures - if (stream->peek() == std::ios::traits_type::eof()) - { - result->toon_filenames.clear(); - } - else { - result->toon_filenames.resize(10); - for (uint32_t i = 0; i < 10; i++) - { - stream->read(buffer, 100); - result->toon_filenames[i] = std::string(buffer); - } - } - - // physics - if (stream->peek() == std::ios::traits_type::eof()) - { - result->rigid_bodies.clear(); - result->constraints.clear(); - } - else { - uint32_t rigid_body_num; - stream->read((char*) &rigid_body_num, sizeof(uint32_t)); - result->rigid_bodies.resize(rigid_body_num); - for (uint32_t i = 0; i < rigid_body_num; i++) - { - result->rigid_bodies[i].Read(stream); - } - uint32_t constraint_num; - stream->read((char*) &constraint_num, sizeof(uint32_t)); - result->constraints.resize(constraint_num); - for (uint32_t i = 0; i < constraint_num; i++) - { - result->constraints[i].Read(stream); - } - } - - if (stream->peek() != std::ios::traits_type::eof()) - { - std::cerr << "there is unknown data" << std::endl; - } - - return result; - } - }; -} diff --git a/thirdparty/assimp/code/MMD/MMDPmxParser.cpp b/thirdparty/assimp/code/MMD/MMDPmxParser.cpp deleted file mode 100644 index 80f0986dd7..0000000000 --- a/thirdparty/assimp/code/MMD/MMDPmxParser.cpp +++ /dev/null @@ -1,608 +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 <utility> -#include "MMDPmxParser.h" -#include <assimp/StringUtils.h> -#ifdef ASSIMP_USE_HUNTER -# include <utf8/utf8.h> -#else -# include "../contrib/utf8cpp/source/utf8.h" -#endif -#include <assimp/Exceptional.h> - -namespace pmx -{ - int ReadIndex(std::istream *stream, int size) - { - switch (size) - { - case 1: - uint8_t tmp8; - stream->read((char*) &tmp8, sizeof(uint8_t)); - if (255 == tmp8) - { - return -1; - } - else { - return (int) tmp8; - } - case 2: - uint16_t tmp16; - stream->read((char*) &tmp16, sizeof(uint16_t)); - if (65535 == tmp16) - { - return -1; - } - else { - return (int) tmp16; - } - case 4: - int tmp32; - stream->read((char*) &tmp32, sizeof(int)); - return tmp32; - default: - return -1; - } - } - - std::string ReadString(std::istream *stream, uint8_t encoding) - { - int size; - stream->read((char*) &size, sizeof(int)); - std::vector<char> buffer; - if (size == 0) - { - return std::string(""); - } - buffer.reserve(size); - stream->read((char*) buffer.data(), size); - if (encoding == 0) - { - // UTF16 to UTF8 - const uint16_t* sourceStart = (uint16_t*)buffer.data(); - const unsigned int targetSize = size * 3; // enough to encode - char *targetStart = new char[targetSize]; - std::memset(targetStart, 0, targetSize * sizeof(char)); - - utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart ); - - std::string result(targetStart); - delete [] targetStart; - return result; - } - else - { - // the name is already UTF8 - return std::string((const char*)buffer.data(), size); - } - } - - void PmxSetting::Read(std::istream *stream) - { - uint8_t count; - stream->read((char*) &count, sizeof(uint8_t)); - if (count < 8) - { - throw DeadlyImportError("MMD: invalid size"); - } - stream->read((char*) &encoding, sizeof(uint8_t)); - stream->read((char*) &uv, sizeof(uint8_t)); - stream->read((char*) &vertex_index_size, sizeof(uint8_t)); - stream->read((char*) &texture_index_size, sizeof(uint8_t)); - stream->read((char*) &material_index_size, sizeof(uint8_t)); - stream->read((char*) &bone_index_size, sizeof(uint8_t)); - stream->read((char*) &morph_index_size, sizeof(uint8_t)); - stream->read((char*) &rigidbody_index_size, sizeof(uint8_t)); - uint8_t temp; - for (int i = 8; i < count; i++) - { - stream->read((char*)&temp, sizeof(uint8_t)); - } - } - - void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_index = ReadIndex(stream, setting->bone_index_size); - } - - void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_index1 = ReadIndex(stream, setting->bone_index_size); - this->bone_index2 = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->bone_weight, sizeof(float)); - } - - void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_index1 = ReadIndex(stream, setting->bone_index_size); - this->bone_index2 = ReadIndex(stream, setting->bone_index_size); - this->bone_index3 = ReadIndex(stream, setting->bone_index_size); - this->bone_index4 = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->bone_weight1, sizeof(float)); - stream->read((char*) &this->bone_weight2, sizeof(float)); - stream->read((char*) &this->bone_weight3, sizeof(float)); - stream->read((char*) &this->bone_weight4, sizeof(float)); - } - - void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_index1 = ReadIndex(stream, setting->bone_index_size); - this->bone_index2 = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->bone_weight, sizeof(float)); - stream->read((char*) this->sdef_c, sizeof(float) * 3); - stream->read((char*) this->sdef_r0, sizeof(float) * 3); - stream->read((char*) this->sdef_r1, sizeof(float) * 3); - } - - void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_index1 = ReadIndex(stream, setting->bone_index_size); - this->bone_index2 = ReadIndex(stream, setting->bone_index_size); - this->bone_index3 = ReadIndex(stream, setting->bone_index_size); - this->bone_index4 = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->bone_weight1, sizeof(float)); - stream->read((char*) &this->bone_weight2, sizeof(float)); - stream->read((char*) &this->bone_weight3, sizeof(float)); - stream->read((char*) &this->bone_weight4, sizeof(float)); - } - - void PmxVertex::Read(std::istream *stream, PmxSetting *setting) - { - stream->read((char*) this->position, sizeof(float) * 3); - stream->read((char*) this->normal, sizeof(float) * 3); - stream->read((char*) this->uv, sizeof(float) * 2); - for (int i = 0; i < setting->uv; ++i) - { - stream->read((char*) this->uva[i], sizeof(float) * 4); - } - stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType)); - switch (this->skinning_type) - { - case PmxVertexSkinningType::BDEF1: - this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>(); - break; - case PmxVertexSkinningType::BDEF2: - this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>(); - break; - case PmxVertexSkinningType::BDEF4: - this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>(); - break; - case PmxVertexSkinningType::SDEF: - this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>(); - break; - case PmxVertexSkinningType::QDEF: - this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>(); - break; - default: - throw "invalid skinning type"; - } - this->skinning->Read(stream, setting); - stream->read((char*) &this->edge, sizeof(float)); - } - - void PmxMaterial::Read(std::istream *stream, PmxSetting *setting) - { - this->material_name = ReadString(stream, setting->encoding); - this->material_english_name = ReadString(stream, setting->encoding); - stream->read((char*) this->diffuse, sizeof(float) * 4); - stream->read((char*) this->specular, sizeof(float) * 3); - stream->read((char*) &this->specularlity, sizeof(float)); - stream->read((char*) this->ambient, sizeof(float) * 3); - stream->read((char*) &this->flag, sizeof(uint8_t)); - stream->read((char*) this->edge_color, sizeof(float) * 4); - stream->read((char*) &this->edge_size, sizeof(float)); - this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size); - this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size); - stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t)); - stream->read((char*) &this->common_toon_flag, sizeof(uint8_t)); - if (this->common_toon_flag) - { - stream->read((char*) &this->toon_texture_index, sizeof(uint8_t)); - } - else { - this->toon_texture_index = ReadIndex(stream, setting->texture_index_size); - } - this->memo = ReadString(stream, setting->encoding); - stream->read((char*) &this->index_count, sizeof(int)); - } - - void PmxIkLink::Read(std::istream *stream, PmxSetting *setting) - { - this->link_target = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->angle_lock, sizeof(uint8_t)); - if (angle_lock == 1) - { - stream->read((char*) this->max_radian, sizeof(float) * 3); - stream->read((char*) this->min_radian, sizeof(float) * 3); - } - } - - void PmxBone::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_name = ReadString(stream, setting->encoding); - this->bone_english_name = ReadString(stream, setting->encoding); - stream->read((char*) this->position, sizeof(float) * 3); - this->parent_index = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->level, sizeof(int)); - stream->read((char*) &this->bone_flag, sizeof(uint16_t)); - if (this->bone_flag & 0x0001) { - this->target_index = ReadIndex(stream, setting->bone_index_size); - } - else { - stream->read((char*)this->offset, sizeof(float) * 3); - } - if (this->bone_flag & (0x0100 | 0x0200)) { - this->grant_parent_index = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->grant_weight, sizeof(float)); - } - if (this->bone_flag & 0x0400) { - stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3); - } - if (this->bone_flag & 0x0800) { - stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3); - stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3); - } - if (this->bone_flag & 0x2000) { - stream->read((char*) &this->key, sizeof(int)); - } - if (this->bone_flag & 0x0020) { - this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &ik_loop, sizeof(int)); - stream->read((char*) &ik_loop_angle_limit, sizeof(float)); - stream->read((char*) &ik_link_count, sizeof(int)); - this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count); - for (int i = 0; i < ik_link_count; i++) { - ik_links[i].Read(stream, setting); - } - } - } - - void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->vertex_index = ReadIndex(stream, setting->vertex_index_size); - stream->read((char*)this->position_offset, sizeof(float) * 3); - } - - void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->vertex_index = ReadIndex(stream, setting->vertex_index_size); - stream->read((char*)this->uv_offset, sizeof(float) * 4); - } - - void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->bone_index = ReadIndex(stream, setting->bone_index_size); - stream->read((char*)this->translation, sizeof(float) * 3); - stream->read((char*)this->rotation, sizeof(float) * 4); - } - - void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->material_index = ReadIndex(stream, setting->material_index_size); - stream->read((char*) &this->offset_operation, sizeof(uint8_t)); - stream->read((char*)this->diffuse, sizeof(float) * 4); - stream->read((char*)this->specular, sizeof(float) * 3); - stream->read((char*) &this->specularity, sizeof(float)); - stream->read((char*)this->ambient, sizeof(float) * 3); - stream->read((char*)this->edge_color, sizeof(float) * 4); - stream->read((char*) &this->edge_size, sizeof(float)); - stream->read((char*)this->texture_argb, sizeof(float) * 4); - stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4); - stream->read((char*)this->toon_texture_argb, sizeof(float) * 4); - } - - void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->morph_index = ReadIndex(stream, setting->morph_index_size); - stream->read((char*) &this->morph_weight, sizeof(float)); - } - - void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->morph_index = ReadIndex(stream, setting->morph_index_size); - stream->read((char*) &this->morph_value, sizeof(float)); - } - - void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting) - { - this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size); - stream->read((char*) &this->is_local, sizeof(uint8_t)); - stream->read((char*)this->velocity, sizeof(float) * 3); - stream->read((char*)this->angular_torque, sizeof(float) * 3); - } - - void PmxMorph::Read(std::istream *stream, PmxSetting *setting) - { - this->morph_name = ReadString(stream, setting->encoding); - this->morph_english_name = ReadString(stream, setting->encoding); - stream->read((char*) &category, sizeof(MorphCategory)); - stream->read((char*) &morph_type, sizeof(MorphType)); - stream->read((char*) &this->offset_count, sizeof(int)); - switch (this->morph_type) - { - case MorphType::Group: - group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count); - for (int i = 0; i < offset_count; i++) - { - group_offsets[i].Read(stream, setting); - } - break; - case MorphType::Vertex: - vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count); - for (int i = 0; i < offset_count; i++) - { - vertex_offsets[i].Read(stream, setting); - } - break; - case MorphType::Bone: - bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count); - for (int i = 0; i < offset_count; i++) - { - bone_offsets[i].Read(stream, setting); - } - break; - case MorphType::Matrial: - material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count); - for (int i = 0; i < offset_count; i++) - { - material_offsets[i].Read(stream, setting); - } - break; - case MorphType::UV: - case MorphType::AdditionalUV1: - case MorphType::AdditionalUV2: - case MorphType::AdditionalUV3: - case MorphType::AdditionalUV4: - uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count); - for (int i = 0; i < offset_count; i++) - { - uv_offsets[i].Read(stream, setting); - } - break; - default: - throw DeadlyImportError("MMD: unknown morth type"); - } - } - - void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting) - { - stream->read((char*) &this->element_target, sizeof(uint8_t)); - if (this->element_target == 0x00) - { - this->index = ReadIndex(stream, setting->bone_index_size); - } - else { - this->index = ReadIndex(stream, setting->morph_index_size); - } - } - - void PmxFrame::Read(std::istream *stream, PmxSetting *setting) - { - this->frame_name = ReadString(stream, setting->encoding); - this->frame_english_name = ReadString(stream, setting->encoding); - stream->read((char*) &this->frame_flag, sizeof(uint8_t)); - stream->read((char*) &this->element_count, sizeof(int)); - this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count); - for (int i = 0; i < this->element_count; i++) - { - this->elements[i].Read(stream, setting); - } - } - - void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting) - { - this->girid_body_name = ReadString(stream, setting->encoding); - this->girid_body_english_name = ReadString(stream, setting->encoding); - this->target_bone = ReadIndex(stream, setting->bone_index_size); - stream->read((char*) &this->group, sizeof(uint8_t)); - stream->read((char*) &this->mask, sizeof(uint16_t)); - stream->read((char*) &this->shape, sizeof(uint8_t)); - stream->read((char*) this->size, sizeof(float) * 3); - stream->read((char*) this->position, sizeof(float) * 3); - stream->read((char*) this->orientation, sizeof(float) * 3); - stream->read((char*) &this->mass, sizeof(float)); - stream->read((char*) &this->move_attenuation, sizeof(float)); - stream->read((char*) &this->rotation_attenuation, sizeof(float)); - stream->read((char*) &this->repulsion, sizeof(float)); - stream->read((char*) &this->friction, sizeof(float)); - stream->read((char*) &this->physics_calc_type, sizeof(uint8_t)); - } - - void PmxJointParam::Read(std::istream *stream, PmxSetting *setting) - { - this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size); - this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size); - stream->read((char*) this->position, sizeof(float) * 3); - stream->read((char*) this->orientaiton, sizeof(float) * 3); - stream->read((char*) this->move_limitation_min, sizeof(float) * 3); - stream->read((char*) this->move_limitation_max, sizeof(float) * 3); - stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3); - stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3); - stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3); - stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3); - } - - void PmxJoint::Read(std::istream *stream, PmxSetting *setting) - { - this->joint_name = ReadString(stream, setting->encoding); - this->joint_english_name = ReadString(stream, setting->encoding); - stream->read((char*) &this->joint_type, sizeof(uint8_t)); - this->param.Read(stream, setting); - } - - void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting) - { - this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size); - this->related_vertex = ReadIndex(stream, setting->vertex_index_size); - stream->read((char*) &this->is_near, sizeof(uint8_t)); - } - - void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/) - { - std::cerr << "Not Implemented Exception" << std::endl; - throw DeadlyImportError("MMD: Not Implemented Exception"); - } - - void PmxModel::Init() - { - this->version = 0.0f; - this->model_name.clear(); - this->model_english_name.clear(); - this->model_comment.clear(); - this->model_english_comment.clear(); - this->vertex_count = 0; - this->vertices = nullptr; - this->index_count = 0; - this->indices = nullptr; - this->texture_count = 0; - this->textures = nullptr; - this->material_count = 0; - this->materials = nullptr; - this->bone_count = 0; - this->bones = nullptr; - this->morph_count = 0; - this->morphs = nullptr; - this->frame_count = 0; - this->frames = nullptr; - this->rigid_body_count = 0; - this->rigid_bodies = nullptr; - this->joint_count = 0; - this->joints = nullptr; - this->soft_body_count = 0; - this->soft_bodies = nullptr; - } - - void PmxModel::Read(std::istream *stream) - { - char magic[4]; - stream->read((char*) magic, sizeof(char) * 4); - if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) - { - std::cerr << "invalid magic number." << std::endl; - throw DeadlyImportError("MMD: invalid magic number."); - } - stream->read((char*) &version, sizeof(float)); - if (version != 2.0f && version != 2.1f) - { - std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; - throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version)); - } - this->setting.Read(stream); - - this->model_name = ReadString(stream, setting.encoding); - this->model_english_name = ReadString(stream, setting.encoding); - this->model_comment = ReadString(stream, setting.encoding); - this->model_english_comment = ReadString(stream, setting.encoding); - - // read vertices - stream->read((char*) &vertex_count, sizeof(int)); - this->vertices = mmd::make_unique<PmxVertex []>(vertex_count); - for (int i = 0; i < vertex_count; i++) - { - vertices[i].Read(stream, &setting); - } - - // read indices - stream->read((char*) &index_count, sizeof(int)); - this->indices = mmd::make_unique<int []>(index_count); - for (int i = 0; i < index_count; i++) - { - this->indices[i] = ReadIndex(stream, setting.vertex_index_size); - } - - // read texture names - stream->read((char*) &texture_count, sizeof(int)); - this->textures = mmd::make_unique<std::string []>(texture_count); - for (int i = 0; i < texture_count; i++) - { - this->textures[i] = ReadString(stream, setting.encoding); - } - - // read materials - stream->read((char*) &material_count, sizeof(int)); - this->materials = mmd::make_unique<PmxMaterial []>(material_count); - for (int i = 0; i < material_count; i++) - { - this->materials[i].Read(stream, &setting); - } - - // read bones - stream->read((char*) &this->bone_count, sizeof(int)); - this->bones = mmd::make_unique<PmxBone []>(this->bone_count); - for (int i = 0; i < this->bone_count; i++) - { - this->bones[i].Read(stream, &setting); - } - - // read morphs - stream->read((char*) &this->morph_count, sizeof(int)); - this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count); - for (int i = 0; i < this->morph_count; i++) - { - this->morphs[i].Read(stream, &setting); - } - - // read display frames - stream->read((char*) &this->frame_count, sizeof(int)); - this->frames = mmd::make_unique<PmxFrame []>(this->frame_count); - for (int i = 0; i < this->frame_count; i++) - { - this->frames[i].Read(stream, &setting); - } - - // read rigid bodies - stream->read((char*) &this->rigid_body_count, sizeof(int)); - this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count); - for (int i = 0; i < this->rigid_body_count; i++) - { - this->rigid_bodies[i].Read(stream, &setting); - } - - // read joints - stream->read((char*) &this->joint_count, sizeof(int)); - this->joints = mmd::make_unique<PmxJoint []>(this->joint_count); - for (int i = 0; i < this->joint_count; i++) - { - this->joints[i].Read(stream, &setting); - } - } -} diff --git a/thirdparty/assimp/code/MMD/MMDPmxParser.h b/thirdparty/assimp/code/MMD/MMDPmxParser.h deleted file mode 100644 index cf523a1298..0000000000 --- a/thirdparty/assimp/code/MMD/MMDPmxParser.h +++ /dev/null @@ -1,782 +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 <vector> -#include <string> -#include <iostream> -#include <fstream> -#include <memory> -#include "MMDCpp14.h" - -namespace pmx -{ - class PmxSetting - { - public: - PmxSetting() - : encoding(0) - , uv(0) - , vertex_index_size(0) - , texture_index_size(0) - , material_index_size(0) - , bone_index_size(0) - , morph_index_size(0) - , rigidbody_index_size(0) - {} - - uint8_t encoding; - uint8_t uv; - uint8_t vertex_index_size; - uint8_t texture_index_size; - uint8_t material_index_size; - uint8_t bone_index_size; - uint8_t morph_index_size; - uint8_t rigidbody_index_size; - void Read(std::istream *stream); - }; - - enum class PmxVertexSkinningType : uint8_t - { - BDEF1 = 0, - BDEF2 = 1, - BDEF4 = 2, - SDEF = 3, - QDEF = 4, - }; - - class PmxVertexSkinning - { - public: - virtual void Read(std::istream *stream, PmxSetting *setting) = 0; - virtual ~PmxVertexSkinning() {} - }; - - class PmxVertexSkinningBDEF1 : public PmxVertexSkinning - { - public: - PmxVertexSkinningBDEF1() - : bone_index(0) - {} - - int bone_index; - void Read(std::istream *stresam, PmxSetting *setting); - }; - - class PmxVertexSkinningBDEF2 : public PmxVertexSkinning - { - public: - PmxVertexSkinningBDEF2() - : bone_index1(0) - , bone_index2(0) - , bone_weight(0.0f) - {} - - int bone_index1; - int bone_index2; - float bone_weight; - void Read(std::istream *stresam, PmxSetting *setting); - }; - - class PmxVertexSkinningBDEF4 : public PmxVertexSkinning - { - public: - PmxVertexSkinningBDEF4() - : bone_index1(0) - , bone_index2(0) - , bone_index3(0) - , bone_index4(0) - , bone_weight1(0.0f) - , bone_weight2(0.0f) - , bone_weight3(0.0f) - , bone_weight4(0.0f) - {} - - int bone_index1; - int bone_index2; - int bone_index3; - int bone_index4; - float bone_weight1; - float bone_weight2; - float bone_weight3; - float bone_weight4; - void Read(std::istream *stresam, PmxSetting *setting); - }; - - class PmxVertexSkinningSDEF : public PmxVertexSkinning - { - public: - PmxVertexSkinningSDEF() - : bone_index1(0) - , bone_index2(0) - , bone_weight(0.0f) - { - for (int i = 0; i < 3; ++i) { - sdef_c[i] = 0.0f; - sdef_r0[i] = 0.0f; - sdef_r1[i] = 0.0f; - } - } - - int bone_index1; - int bone_index2; - float bone_weight; - float sdef_c[3]; - float sdef_r0[3]; - float sdef_r1[3]; - void Read(std::istream *stresam, PmxSetting *setting); - }; - - class PmxVertexSkinningQDEF : public PmxVertexSkinning - { - public: - PmxVertexSkinningQDEF() - : bone_index1(0) - , bone_index2(0) - , bone_index3(0) - , bone_index4(0) - , bone_weight1(0.0f) - , bone_weight2(0.0f) - , bone_weight3(0.0f) - , bone_weight4(0.0f) - {} - - int bone_index1; - int bone_index2; - int bone_index3; - int bone_index4; - float bone_weight1; - float bone_weight2; - float bone_weight3; - float bone_weight4; - void Read(std::istream *stresam, PmxSetting *setting); - }; - - class PmxVertex - { - public: - PmxVertex() - : edge(0.0f) - { - uv[0] = uv[1] = 0.0f; - for (int i = 0; i < 3; ++i) { - position[i] = 0.0f; - normal[i] = 0.0f; - } - for (int i = 0; i < 4; ++i) { - for (int k = 0; k < 4; ++k) { - uva[i][k] = 0.0f; - } - } - } - - float position[3]; - float normal[3]; - float uv[2]; - float uva[4][4]; - PmxVertexSkinningType skinning_type; - std::unique_ptr<PmxVertexSkinning> skinning; - float edge; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxMaterial - { - public: - PmxMaterial() - : specularlity(0.0f) - , flag(0) - , edge_size(0.0f) - , diffuse_texture_index(0) - , sphere_texture_index(0) - , sphere_op_mode(0) - , common_toon_flag(0) - , toon_texture_index(0) - , index_count(0) - { - for (int i = 0; i < 3; ++i) { - specular[i] = 0.0f; - ambient[i] = 0.0f; - edge_color[i] = 0.0f; - } - for (int i = 0; i < 4; ++i) { - diffuse[i] = 0.0f; - } - } - - std::string material_name; - std::string material_english_name; - float diffuse[4]; - float specular[3]; - float specularlity; - float ambient[3]; - uint8_t flag; - float edge_color[4]; - float edge_size; - int diffuse_texture_index; - int sphere_texture_index; - uint8_t sphere_op_mode; - uint8_t common_toon_flag; - int toon_texture_index; - std::string memo; - int index_count; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxIkLink - { - public: - PmxIkLink() - : link_target(0) - , angle_lock(0) - { - for (int i = 0; i < 3; ++i) { - max_radian[i] = 0.0f; - min_radian[i] = 0.0f; - } - } - - int link_target; - uint8_t angle_lock; - float max_radian[3]; - float min_radian[3]; - void Read(std::istream *stream, PmxSetting *settingn); - }; - - class PmxBone - { - public: - PmxBone() - : parent_index(0) - , level(0) - , bone_flag(0) - , target_index(0) - , grant_parent_index(0) - , grant_weight(0.0f) - , key(0) - , ik_target_bone_index(0) - , ik_loop(0) - , ik_loop_angle_limit(0.0f) - , ik_link_count(0) - { - for (int i = 0; i < 3; ++i) { - position[i] = 0.0f; - offset[i] = 0.0f; - lock_axis_orientation[i] = 0.0f; - local_axis_x_orientation[i] = 0.0f; - local_axis_y_orientation[i] = 0.0f; - } - } - - std::string bone_name; - std::string bone_english_name; - float position[3]; - int parent_index; - int level; - uint16_t bone_flag; - float offset[3]; - int target_index; - int grant_parent_index; - float grant_weight; - float lock_axis_orientation[3]; - float local_axis_x_orientation[3]; - float local_axis_y_orientation[3]; - int key; - int ik_target_bone_index; - int ik_loop; - float ik_loop_angle_limit; - int ik_link_count; - std::unique_ptr<PmxIkLink []> ik_links; - void Read(std::istream *stream, PmxSetting *setting); - }; - - enum class MorphType : uint8_t - { - Group = 0, - Vertex = 1, - Bone = 2, - UV = 3, - AdditionalUV1 = 4, - AdditionalUV2 = 5, - AdditionalUV3 = 6, - AdditionalUV4 = 7, - Matrial = 8, - Flip = 9, - Implus = 10, - }; - - enum class MorphCategory : uint8_t - { - ReservedCategory = 0, - Eyebrow = 1, - Eye = 2, - Mouth = 3, - Other = 4, - }; - - class PmxMorphOffset - { - public: - void virtual Read(std::istream *stream, PmxSetting *setting) = 0; - }; - - class PmxMorphVertexOffset : public PmxMorphOffset - { - public: - PmxMorphVertexOffset() - : vertex_index(0) - { - for (int i = 0; i < 3; ++i) { - position_offset[i] = 0.0f; - } - } - int vertex_index; - float position_offset[3]; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorphUVOffset : public PmxMorphOffset - { - public: - PmxMorphUVOffset() - : vertex_index(0) - { - for (int i = 0; i < 4; ++i) { - uv_offset[i] = 0.0f; - } - } - int vertex_index; - float uv_offset[4]; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorphBoneOffset : public PmxMorphOffset - { - public: - PmxMorphBoneOffset() - : bone_index(0) - { - for (int i = 0; i < 3; ++i) { - translation[i] = 0.0f; - } - for (int i = 0; i < 4; ++i) { - rotation[i] = 0.0f; - } - } - int bone_index; - float translation[3]; - float rotation[4]; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorphMaterialOffset : public PmxMorphOffset - { - public: - PmxMorphMaterialOffset() - : specularity(0.0f) - , edge_size(0.0f) - { - for (int i = 0; i < 3; ++i) { - specular[i] = 0.0f; - ambient[i] = 0.0f; - } - for (int i = 0; i < 4; ++i) { - diffuse[i] = 0.0f; - edge_color[i] = 0.0f; - texture_argb[i] = 0.0f; - sphere_texture_argb[i] = 0.0f; - toon_texture_argb[i] = 0.0f; - } - } - int material_index; - uint8_t offset_operation; - float diffuse[4]; - float specular[3]; - float specularity; - float ambient[3]; - float edge_color[4]; - float edge_size; - float texture_argb[4]; - float sphere_texture_argb[4]; - float toon_texture_argb[4]; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorphGroupOffset : public PmxMorphOffset - { - public: - PmxMorphGroupOffset() - : morph_index(0) - , morph_weight(0.0f) - {} - int morph_index; - float morph_weight; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorphFlipOffset : public PmxMorphOffset - { - public: - PmxMorphFlipOffset() - : morph_index(0) - , morph_value(0.0f) - {} - int morph_index; - float morph_value; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorphImplusOffset : public PmxMorphOffset - { - public: - PmxMorphImplusOffset() - : rigid_body_index(0) - , is_local(0) - { - for (int i = 0; i < 3; ++i) { - velocity[i] = 0.0f; - angular_torque[i] = 0.0f; - } - } - int rigid_body_index; - uint8_t is_local; - float velocity[3]; - float angular_torque[3]; - void Read(std::istream *stream, PmxSetting *setting); //override; - }; - - class PmxMorph - { - public: - PmxMorph() - : offset_count(0) - { - } - std::string morph_name; - std::string morph_english_name; - MorphCategory category; - MorphType morph_type; - int offset_count; - std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets; - std::unique_ptr<PmxMorphUVOffset []> uv_offsets; - std::unique_ptr<PmxMorphBoneOffset []> bone_offsets; - std::unique_ptr<PmxMorphMaterialOffset []> material_offsets; - std::unique_ptr<PmxMorphGroupOffset []> group_offsets; - std::unique_ptr<PmxMorphFlipOffset []> flip_offsets; - std::unique_ptr<PmxMorphImplusOffset []> implus_offsets; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxFrameElement - { - public: - PmxFrameElement() - : element_target(0) - , index(0) - { - } - uint8_t element_target; - int index; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxFrame - { - public: - PmxFrame() - : frame_flag(0) - , element_count(0) - { - } - std::string frame_name; - std::string frame_english_name; - uint8_t frame_flag; - int element_count; - std::unique_ptr<PmxFrameElement []> elements; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxRigidBody - { - public: - PmxRigidBody() - : target_bone(0) - , group(0) - , mask(0) - , shape(0) - , mass(0.0f) - , move_attenuation(0.0f) - , rotation_attenuation(0.0f) - , repulsion(0.0f) - , friction(0.0f) - , physics_calc_type(0) - { - for (int i = 0; i < 3; ++i) { - size[i] = 0.0f; - position[i] = 0.0f; - orientation[i] = 0.0f; - } - } - std::string girid_body_name; - std::string girid_body_english_name; - int target_bone; - uint8_t group; - uint16_t mask; - uint8_t shape; - float size[3]; - float position[3]; - float orientation[3]; - float mass; - float move_attenuation; - float rotation_attenuation; - float repulsion; - float friction; - uint8_t physics_calc_type; - void Read(std::istream *stream, PmxSetting *setting); - }; - - enum class PmxJointType : uint8_t - { - Generic6DofSpring = 0, - Generic6Dof = 1, - Point2Point = 2, - ConeTwist = 3, - Slider = 5, - Hinge = 6 - }; - - class PmxJointParam - { - public: - PmxJointParam() - : rigid_body1(0) - , rigid_body2(0) - { - for (int i = 0; i < 3; ++i) { - position[i] = 0.0f; - orientaiton[i] = 0.0f; - move_limitation_min[i] = 0.0f; - move_limitation_max[i] = 0.0f; - rotation_limitation_min[i] = 0.0f; - rotation_limitation_max[i] = 0.0f; - spring_move_coefficient[i] = 0.0f; - spring_rotation_coefficient[i] = 0.0f; - } - } - int rigid_body1; - int rigid_body2; - float position[3]; - float orientaiton[3]; - float move_limitation_min[3]; - float move_limitation_max[3]; - float rotation_limitation_min[3]; - float rotation_limitation_max[3]; - float spring_move_coefficient[3]; - float spring_rotation_coefficient[3]; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxJoint - { - public: - std::string joint_name; - std::string joint_english_name; - PmxJointType joint_type; - PmxJointParam param; - void Read(std::istream *stream, PmxSetting *setting); - }; - - enum PmxSoftBodyFlag : uint8_t - { - BLink = 0x01, - Cluster = 0x02, - Link = 0x04 - }; - - class PmxAncherRigidBody - { - public: - PmxAncherRigidBody() - : related_rigid_body(0) - , related_vertex(0) - , is_near(false) - {} - int related_rigid_body; - int related_vertex; - bool is_near; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxSoftBody - { - public: - PmxSoftBody() - : shape(0) - , target_material(0) - , group(0) - , mask(0) - , blink_distance(0) - , cluster_count(0) - , mass(0.0) - , collisioni_margin(0.0) - , aero_model(0) - , VCF(0.0f) - , DP(0.0f) - , DG(0.0f) - , LF(0.0f) - , PR(0.0f) - , VC(0.0f) - , DF(0.0f) - , MT(0.0f) - , CHR(0.0f) - , KHR(0.0f) - , SHR(0.0f) - , AHR(0.0f) - , SRHR_CL(0.0f) - , SKHR_CL(0.0f) - , SSHR_CL(0.0f) - , SR_SPLT_CL(0.0f) - , SK_SPLT_CL(0.0f) - , SS_SPLT_CL(0.0f) - , V_IT(0) - , P_IT(0) - , D_IT(0) - , C_IT(0) - , LST(0.0f) - , AST(0.0f) - , VST(0.0f) - , anchor_count(0) - , pin_vertex_count(0) - {} - std::string soft_body_name; - std::string soft_body_english_name; - uint8_t shape; - int target_material; - uint8_t group; - uint16_t mask; - PmxSoftBodyFlag flag; - int blink_distance; - int cluster_count; - float mass; - float collisioni_margin; - int aero_model; - float VCF; - float DP; - float DG; - float LF; - float PR; - float VC; - float DF; - float MT; - float CHR; - float KHR; - float SHR; - float AHR; - float SRHR_CL; - float SKHR_CL; - float SSHR_CL; - float SR_SPLT_CL; - float SK_SPLT_CL; - float SS_SPLT_CL; - int V_IT; - int P_IT; - int D_IT; - int C_IT; - float LST; - float AST; - float VST; - int anchor_count; - std::unique_ptr<PmxAncherRigidBody []> anchers; - int pin_vertex_count; - std::unique_ptr<int []> pin_vertices; - void Read(std::istream *stream, PmxSetting *setting); - }; - - class PmxModel - { - public: - PmxModel() - : version(0.0f) - , vertex_count(0) - , index_count(0) - , texture_count(0) - , material_count(0) - , bone_count(0) - , morph_count(0) - , frame_count(0) - , rigid_body_count(0) - , joint_count(0) - , soft_body_count(0) - {} - - float version; - PmxSetting setting; - std::string model_name; - std::string model_english_name; - std::string model_comment; - std::string model_english_comment; - int vertex_count; - std::unique_ptr<PmxVertex []> vertices; - int index_count; - std::unique_ptr<int []> indices; - int texture_count; - std::unique_ptr< std::string []> textures; - int material_count; - std::unique_ptr<PmxMaterial []> materials; - int bone_count; - std::unique_ptr<PmxBone []> bones; - int morph_count; - std::unique_ptr<PmxMorph []> morphs; - int frame_count; - std::unique_ptr<PmxFrame [] > frames; - int rigid_body_count; - std::unique_ptr<PmxRigidBody []> rigid_bodies; - int joint_count; - std::unique_ptr<PmxJoint []> joints; - int soft_body_count; - std::unique_ptr<PmxSoftBody []> soft_bodies; - void Init(); - void Read(std::istream *stream); - //static std::unique_ptr<PmxModel> ReadFromFile(const char *filename); - //static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream); - }; -} diff --git a/thirdparty/assimp/code/MMD/MMDVmdParser.h b/thirdparty/assimp/code/MMD/MMDVmdParser.h deleted file mode 100644 index 947c3a2422..0000000000 --- a/thirdparty/assimp/code/MMD/MMDVmdParser.h +++ /dev/null @@ -1,376 +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 <vector> -#include <string> -#include <memory> -#include <iostream> -#include <fstream> -#include <ostream> -#include "MMDCpp14.h" - -namespace vmd -{ - class VmdBoneFrame - { - public: - std::string name; - int frame; - float position[3]; - float orientation[4]; - char interpolation[4][4][4]; - - void Read(std::istream* stream) - { - char buffer[15]; - stream->read((char*) buffer, sizeof(char)*15); - name = std::string(buffer); - stream->read((char*) &frame, sizeof(int)); - stream->read((char*) position, sizeof(float)*3); - stream->read((char*) orientation, sizeof(float)*4); - stream->read((char*) interpolation, sizeof(char) * 4 * 4 * 4); - } - - void Write(std::ostream* stream) - { - stream->write((char*)name.c_str(), sizeof(char) * 15); - stream->write((char*)&frame, sizeof(int)); - stream->write((char*)position, sizeof(float) * 3); - stream->write((char*)orientation, sizeof(float) * 4); - stream->write((char*)interpolation, sizeof(char) * 4 * 4 * 4); - } - }; - - class VmdFaceFrame - { - public: - std::string face_name; - float weight; - uint32_t frame; - - void Read(std::istream* stream) - { - char buffer[15]; - stream->read((char*) &buffer, sizeof(char) * 15); - face_name = std::string(buffer); - stream->read((char*) &frame, sizeof(int)); - stream->read((char*) &weight, sizeof(float)); - } - - void Write(std::ostream* stream) - { - stream->write((char*)face_name.c_str(), sizeof(char) * 15); - stream->write((char*)&frame, sizeof(int)); - stream->write((char*)&weight, sizeof(float)); - } - }; - - class VmdCameraFrame - { - public: - int frame; - float distance; - float position[3]; - float orientation[3]; - char interpolation[6][4]; - float angle; - char unknown[3]; - - void Read(std::istream *stream) - { - stream->read((char*) &frame, sizeof(int)); - stream->read((char*) &distance, sizeof(float)); - stream->read((char*) position, sizeof(float) * 3); - stream->read((char*) orientation, sizeof(float) * 3); - stream->read((char*) interpolation, sizeof(char) * 24); - stream->read((char*) &angle, sizeof(float)); - stream->read((char*) unknown, sizeof(char) * 3); - } - - void Write(std::ostream *stream) - { - stream->write((char*)&frame, sizeof(int)); - stream->write((char*)&distance, sizeof(float)); - stream->write((char*)position, sizeof(float) * 3); - stream->write((char*)orientation, sizeof(float) * 3); - stream->write((char*)interpolation, sizeof(char) * 24); - stream->write((char*)&angle, sizeof(float)); - stream->write((char*)unknown, sizeof(char) * 3); - } - }; - - class VmdLightFrame - { - public: - int frame; - float color[3]; - float position[3]; - - void Read(std::istream* stream) - { - stream->read((char*) &frame, sizeof(int)); - stream->read((char*) color, sizeof(float) * 3); - stream->read((char*) position, sizeof(float) * 3); - } - - void Write(std::ostream* stream) - { - stream->write((char*)&frame, sizeof(int)); - stream->write((char*)color, sizeof(float) * 3); - stream->write((char*)position, sizeof(float) * 3); - } - }; - - class VmdIkEnable - { - public: - std::string ik_name; - bool enable; - }; - - class VmdIkFrame - { - public: - int frame; - bool display; - std::vector<VmdIkEnable> ik_enable; - - void Read(std::istream *stream) - { - char buffer[20]; - stream->read((char*) &frame, sizeof(int)); - stream->read((char*) &display, sizeof(uint8_t)); - int ik_count; - stream->read((char*) &ik_count, sizeof(int)); - ik_enable.resize(ik_count); - for (int i = 0; i < ik_count; i++) - { - stream->read(buffer, 20); - ik_enable[i].ik_name = std::string(buffer); - stream->read((char*) &ik_enable[i].enable, sizeof(uint8_t)); - } - } - - void Write(std::ostream *stream) - { - stream->write((char*)&frame, sizeof(int)); - stream->write((char*)&display, sizeof(uint8_t)); - int ik_count = static_cast<int>(ik_enable.size()); - stream->write((char*)&ik_count, sizeof(int)); - for (int i = 0; i < ik_count; i++) - { - const VmdIkEnable& ik_enable = this->ik_enable.at(i); - stream->write(ik_enable.ik_name.c_str(), 20); - stream->write((char*)&ik_enable.enable, sizeof(uint8_t)); - } - } - }; - - class VmdMotion - { - public: - std::string model_name; - int version; - std::vector<VmdBoneFrame> bone_frames; - std::vector<VmdFaceFrame> face_frames; - std::vector<VmdCameraFrame> camera_frames; - std::vector<VmdLightFrame> light_frames; - std::vector<VmdIkFrame> ik_frames; - - static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename) - { - std::ifstream stream(filename, std::ios::binary); - auto result = LoadFromStream(&stream); - stream.close(); - return result; - } - - static std::unique_ptr<VmdMotion> LoadFromStream(std::ifstream *stream) - { - - char buffer[30]; - auto result = mmd::make_unique<VmdMotion>(); - - // magic and version - stream->read((char*) buffer, 30); - if (strncmp(buffer, "Vocaloid Motion Data", 20)) - { - std::cerr << "invalid vmd file." << std::endl; - return nullptr; - } - result->version = std::atoi(buffer + 20); - - // name - stream->read(buffer, 20); - result->model_name = std::string(buffer); - - // bone frames - int bone_frame_num; - stream->read((char*) &bone_frame_num, sizeof(int)); - result->bone_frames.resize(bone_frame_num); - for (int i = 0; i < bone_frame_num; i++) - { - result->bone_frames[i].Read(stream); - } - - // face frames - int face_frame_num; - stream->read((char*) &face_frame_num, sizeof(int)); - result->face_frames.resize(face_frame_num); - for (int i = 0; i < face_frame_num; i++) - { - result->face_frames[i].Read(stream); - } - - // camera frames - int camera_frame_num; - stream->read((char*) &camera_frame_num, sizeof(int)); - result->camera_frames.resize(camera_frame_num); - for (int i = 0; i < camera_frame_num; i++) - { - result->camera_frames[i].Read(stream); - } - - // light frames - int light_frame_num; - stream->read((char*) &light_frame_num, sizeof(int)); - result->light_frames.resize(light_frame_num); - for (int i = 0; i < light_frame_num; i++) - { - result->light_frames[i].Read(stream); - } - - // unknown2 - stream->read(buffer, 4); - - // ik frames - if (stream->peek() != std::ios::traits_type::eof()) - { - int ik_num; - stream->read((char*) &ik_num, sizeof(int)); - result->ik_frames.resize(ik_num); - for (int i = 0; i < ik_num; i++) - { - result->ik_frames[i].Read(stream); - } - } - - if (stream->peek() != std::ios::traits_type::eof()) - { - std::cerr << "vmd stream has unknown data." << std::endl; - } - - return result; - } - - bool SaveToFile(const std::u16string& /*filename*/) - { - // TODO: How to adapt u16string to string? - /* - std::ofstream stream(filename.c_str(), std::ios::binary); - auto result = SaveToStream(&stream); - stream.close(); - return result; - */ - return false; - } - - bool SaveToStream(std::ofstream *stream) - { - std::string magic = "Vocaloid Motion Data 0002\0"; - magic.resize(30); - - // magic and version - stream->write(magic.c_str(), 30); - - // name - stream->write(model_name.c_str(), 20); - - // bone frames - const int bone_frame_num = static_cast<int>(bone_frames.size()); - stream->write(reinterpret_cast<const char*>(&bone_frame_num), sizeof(int)); - for (int i = 0; i < bone_frame_num; i++) - { - bone_frames[i].Write(stream); - } - - // face frames - const int face_frame_num = static_cast<int>(face_frames.size()); - stream->write(reinterpret_cast<const char*>(&face_frame_num), sizeof(int)); - for (int i = 0; i < face_frame_num; i++) - { - face_frames[i].Write(stream); - } - - // camera frames - const int camera_frame_num = static_cast<int>(camera_frames.size()); - stream->write(reinterpret_cast<const char*>(&camera_frame_num), sizeof(int)); - for (int i = 0; i < camera_frame_num; i++) - { - camera_frames[i].Write(stream); - } - - // light frames - const int light_frame_num = static_cast<int>(light_frames.size()); - stream->write(reinterpret_cast<const char*>(&light_frame_num), sizeof(int)); - for (int i = 0; i < light_frame_num; i++) - { - light_frames[i].Write(stream); - } - - // self shadow datas - const int self_shadow_num = 0; - stream->write(reinterpret_cast<const char*>(&self_shadow_num), sizeof(int)); - - // ik frames - const int ik_num = static_cast<int>(ik_frames.size()); - stream->write(reinterpret_cast<const char*>(&ik_num), sizeof(int)); - for (int i = 0; i < ik_num; i++) - { - ik_frames[i].Write(stream); - } - - return true; - } - }; -} diff --git a/thirdparty/assimp/code/Material/MaterialSystem.cpp b/thirdparty/assimp/code/Material/MaterialSystem.cpp index d0b39093b6..0be6e9f7bb 100644 --- a/thirdparty/assimp/code/Material/MaterialSystem.cpp +++ b/thirdparty/assimp/code/Material/MaterialSystem.cpp @@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assimp/types.h> #include <assimp/material.h> #include <assimp/DefaultLogger.hpp> -#include <assimp/Macros.h> using namespace Assimp; @@ -545,23 +544,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput, unsigned int type, unsigned int index) { - // We don't want to add the whole buffer .. write a 32 bit length - // prefix followed by the zero-terminated UTF8 string. - // (HACK) I don't want to break the ABI now, but we definitely - // ought to change aiString::mLength to uint32_t one day. - if (sizeof(size_t) == 8) { - aiString copy = *pInput; - uint32_t* s = reinterpret_cast<uint32_t*>(©.length); - s[1] = static_cast<uint32_t>(pInput->length); - - return AddBinaryProperty(s+1, - static_cast<unsigned int>(pInput->length+1+4), - pKey, - type, - index, - aiPTI_String); - } - ai_assert(sizeof(size_t)==4); + ai_assert(sizeof(ai_uint32)==4); return AddBinaryProperty(pInput, static_cast<unsigned int>(pInput->length+1+4), pKey, diff --git a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp new file mode 100644 index 0000000000..75daeb6b59 --- /dev/null +++ b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp @@ -0,0 +1,268 @@ +/* +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 new file mode 100644 index 0000000000..aa1ad7c80c --- /dev/null +++ b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h @@ -0,0 +1,112 @@ +/* +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/ComputeUVMappingProcess.cpp b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp index bb571a551b..df4d44337d 100644 --- a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp +++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp @@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& } else if (axis * base_axis_z >= angle_epsilon) { FindMeshCenter(mesh, center, min, max); - diffu = max.y - min.y; - diffv = max.z - min.z; + 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.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0); + 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 diff --git a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp index 433f042448..016884c6e7 100644 --- a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp +++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp @@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FindInvalidDataProcess.h" #include "ProcessHelper.h" -#include <assimp/Macros.h> #include <assimp/Exceptional.h> #include <assimp/qnan.h> diff --git a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp index 914ec05b46..f121fc60d3 100644 --- a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp +++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp @@ -431,31 +431,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) bone->mWeights = new aiVertexWeight[bone->mNumWeights]; memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight)); } - else { - - /* NOTE: - * - * In the algorithm above we're assuming that there are no vertices - * with a different bone weight setup at the same position. That wouldn't - * make sense, but it is not absolutely impossible. SkeletonMeshBuilder - * for example generates such input data if two skeleton points - * share the same position. Again this doesn't make sense but is - * reality for some model formats (MD5 for example uses these special - * nodes as attachment tags for its weapons). - * - * Then it is possible that a bone has no weights anymore .... as a quick - * workaround, we're just removing these bones. If they're animated, - * model geometry might be modified but at least there's no risk of a crash. - */ - delete bone; - --pMesh->mNumBones; - for (unsigned int n = a; n < pMesh->mNumBones; ++n) { - pMesh->mBones[n] = pMesh->mBones[n+1]; - } - - --a; - ASSIMP_LOG_WARN("Removing bone -> no weights remaining"); - } } return pMesh->mNumVertices; } diff --git a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp index 50ff5ed93d..41f50a5ba5 100644 --- a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp +++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp @@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh) } 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 index 1adf8e2f69..8565d5933a 100644 --- a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h +++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h @@ -94,6 +94,13 @@ public: * @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: diff --git a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp index 712fd6943d..75d1b6ef78 100644 --- a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp +++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp @@ -538,13 +538,17 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation) { Validate(&pAnimation->mName); - // validate all materials - if (pAnimation->mNumChannels) + // validate all animations + if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels) { - if (!pAnimation->mChannels) { + 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]) @@ -554,6 +558,15 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation) } 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."); @@ -903,6 +916,48 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation, } } +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) { @@ -958,7 +1013,7 @@ void ValidateDSProcess::Validate( const aiString* pString) { if (pString->length > MAXLEN) { - ReportError("aiString::length is too large (%lu, maximum is %lu)", + ReportError("aiString::length is too large (%u, maximum is %lu)", pString->length,MAXLEN); } const char* sz = pString->data; diff --git a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h index 0b891ef414..7b309c9251 100644 --- a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h +++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h @@ -55,6 +55,7 @@ struct aiBone; struct aiMesh; struct aiAnimation; struct aiNodeAnim; +struct aiMeshMorphAnim; struct aiTexture; struct aiMaterial; struct aiNode; @@ -150,6 +151,13 @@ protected: 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*/ diff --git a/thirdparty/assimp/code/revision.h b/thirdparty/assimp/code/revision.h index 88872aef22..66eb875303 100644 --- a/thirdparty/assimp/code/revision.h +++ b/thirdparty/assimp/code/revision.h @@ -1,7 +1,28 @@ #ifndef ASSIMP_REVISION_H_INC #define ASSIMP_REVISION_H_INC -#define GitVersion 0x00000000 +#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 diff --git a/thirdparty/assimp/include/assimp/.editorconfig b/thirdparty/assimp/include/assimp/.editorconfig new file mode 100644 index 0000000000..9ea66423ad --- /dev/null +++ b/thirdparty/assimp/include/assimp/.editorconfig @@ -0,0 +1,8 @@ +# 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 index 55f7fe3754..ad8a3dafd8 100644 --- a/thirdparty/assimp/include/assimp/BaseImporter.h +++ b/thirdparty/assimp/include/assimp/BaseImporter.h @@ -41,9 +41,14 @@ 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> @@ -191,16 +196,13 @@ public: /** * 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: 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 = { - {ImporterUnits::M, 1}, - {ImporterUnits::CM, 0.01}, - {ImporterUnits::MM, 0.001}, - {ImporterUnits::INCHES, 0.0254}, - {ImporterUnits::FEET, 0.3048} - }; + std::map<ImporterUnits, double> importerUnits; virtual void SetApplicationUnits( const ImporterUnits& unit ) { diff --git a/thirdparty/assimp/include/assimp/Bitmap.h b/thirdparty/assimp/include/assimp/Bitmap.h index e6b5fb1327..4c3f5a437b 100644 --- a/thirdparty/assimp/include/assimp/Bitmap.h +++ b/thirdparty/assimp/include/assimp/Bitmap.h @@ -46,10 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * 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> diff --git a/thirdparty/assimp/include/assimp/ByteSwapper.h b/thirdparty/assimp/include/assimp/ByteSwapper.h index 20a2463fb8..3f14c471a8 100644 --- a/thirdparty/assimp/include/assimp/ByteSwapper.h +++ b/thirdparty/assimp/include/assimp/ByteSwapper.h @@ -42,9 +42,14 @@ 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> diff --git a/thirdparty/assimp/include/assimp/CreateAnimMesh.h b/thirdparty/assimp/include/assimp/CreateAnimMesh.h index a60173588f..1266d1de11 100644 --- a/thirdparty/assimp/include/assimp/CreateAnimMesh.h +++ b/thirdparty/assimp/include/assimp/CreateAnimMesh.h @@ -43,16 +43,26 @@ 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 { +namespace Assimp { -/** Create aiAnimMesh from aiMesh. */ +/** + * 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 index 994d728ff5..c6d382c1b5 100644 --- a/thirdparty/assimp/include/assimp/DefaultIOStream.h +++ b/thirdparty/assimp/include/assimp/DefaultIOStream.h @@ -41,15 +41,20 @@ 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 { +namespace Assimp { // ---------------------------------------------------------------------------------- //! @class DefaultIOStream @@ -57,8 +62,7 @@ namespace Assimp { //! @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 -{ +class ASSIMP_API DefaultIOStream : public IOStream { friend class DefaultIOSystem; #if __ANDROID__ # if __ANDROID_API__ > 9 @@ -82,7 +86,6 @@ public: size_t pSize, size_t pCount); - // ------------------------------------------------------------------- /// Write to stream size_t Write(const void* pvBuffer, @@ -107,16 +110,13 @@ public: void Flush(); private: - // File data-structure, using clib FILE* mFile; - // Filename std::string mFilename; - // Cached file size mutable size_t mCachedSize; }; // ---------------------------------------------------------------------------------- -inline +AI_FORCE_INLINE DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT : mFile(nullptr) , mFilename("") @@ -125,7 +125,7 @@ DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT } // ---------------------------------------------------------------------------------- -inline +AI_FORCE_INLINE DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) : mFile(pFile) , mFilename(strFilename) @@ -137,4 +137,3 @@ DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) } // ns assimp #endif //!!AI_DEFAULTIOSTREAM_H_INC - diff --git a/thirdparty/assimp/include/assimp/DefaultIOSystem.h b/thirdparty/assimp/include/assimp/DefaultIOSystem.h index 2dd5c801b5..46f6d447c5 100644 --- a/thirdparty/assimp/include/assimp/DefaultIOSystem.h +++ b/thirdparty/assimp/include/assimp/DefaultIOSystem.h @@ -41,9 +41,14 @@ 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 { diff --git a/thirdparty/assimp/include/assimp/Defines.h b/thirdparty/assimp/include/assimp/Defines.h index 15e1d83c26..be3e2fafd6 100644 --- a/thirdparty/assimp/include/assimp/Defines.h +++ b/thirdparty/assimp/include/assimp/Defines.h @@ -38,6 +38,14 @@ 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)) @@ -47,3 +55,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 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 index 5109b8f077..6bb6ce1e39 100644 --- a/thirdparty/assimp/include/assimp/Exceptional.h +++ b/thirdparty/assimp/include/assimp/Exceptional.h @@ -38,11 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#ifndef INCLUDED_EXCEPTIONAL_H -#define INCLUDED_EXCEPTIONAL_H +#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 @@ -53,17 +59,14 @@ using std::runtime_error; /** 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 -{ +class DeadlyImportError : public runtime_error { public: /** Constructor with arguments */ explicit DeadlyImportError( const std::string& errorText) - : runtime_error(errorText) - { + : runtime_error(errorText) { + // empty } -private: }; typedef DeadlyImportError DeadlyExportError; @@ -84,7 +87,7 @@ struct ExceptionSwallower { template <typename T> struct ExceptionSwallower<T*> { T* operator ()() const { - return NULL; + return nullptr; } }; @@ -122,4 +125,4 @@ struct ExceptionSwallower<void> { }\ } -#endif // INCLUDED_EXCEPTIONAL_H +#endif // AI_INCLUDED_EXCEPTIONAL_H diff --git a/thirdparty/assimp/include/assimp/Exporter.hpp b/thirdparty/assimp/include/assimp/Exporter.hpp index ea0303e804..2612e1f9d2 100644 --- a/thirdparty/assimp/include/assimp/Exporter.hpp +++ b/thirdparty/assimp/include/assimp/Exporter.hpp @@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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" diff --git a/thirdparty/assimp/include/assimp/GenericProperty.h b/thirdparty/assimp/include/assimp/GenericProperty.h index 183ecd5197..7796d595b8 100644 --- a/thirdparty/assimp/include/assimp/GenericProperty.h +++ b/thirdparty/assimp/include/assimp/GenericProperty.h @@ -40,12 +40,17 @@ 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 "Hash.h" +#include <assimp/Hash.h> #include <map> diff --git a/thirdparty/assimp/include/assimp/Hash.h b/thirdparty/assimp/include/assimp/Hash.h index 30657be198..9056440789 100644 --- a/thirdparty/assimp/include/assimp/Hash.h +++ b/thirdparty/assimp/include/assimp/Hash.h @@ -39,10 +39,14 @@ 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> diff --git a/thirdparty/assimp/include/assimp/IOStream.hpp b/thirdparty/assimp/include/assimp/IOStream.hpp index 0623d0f70b..39932cd949 100644 --- a/thirdparty/assimp/include/assimp/IOStream.hpp +++ b/thirdparty/assimp/include/assimp/IOStream.hpp @@ -48,14 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_IOSTREAM_H_INC #define AI_IOSTREAM_H_INC -#include "types.h" +#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 { +namespace Assimp { // ---------------------------------------------------------------------------------- /** @brief CPP-API: Class to handle file I/O for C++ @@ -125,13 +129,13 @@ public: }; //! class IOStream // ---------------------------------------------------------------------------------- -inline +AI_FORCE_INLINE IOStream::IOStream() AI_NO_EXCEPT { // empty } // ---------------------------------------------------------------------------------- -inline +AI_FORCE_INLINE IOStream::~IOStream() { // empty } diff --git a/thirdparty/assimp/include/assimp/IOStreamBuffer.h b/thirdparty/assimp/include/assimp/IOStreamBuffer.h index 58abd97a02..97c84b23e2 100644 --- a/thirdparty/assimp/include/assimp/IOStreamBuffer.h +++ b/thirdparty/assimp/include/assimp/IOStreamBuffer.h @@ -1,5 +1,3 @@ -#pragma once - /* Open Asset Import Library (assimp) ---------------------------------------------------------------------- @@ -42,10 +40,17 @@ 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 "ParsingUtils.h" +#include <assimp/ParsingUtils.h> #include <vector> @@ -124,7 +129,7 @@ private: }; template<class T> -inline +AI_FORCE_INLINE IOStreamBuffer<T>::IOStreamBuffer( size_t cache ) : m_stream( nullptr ) , m_filesize( 0 ) @@ -138,13 +143,13 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache ) } template<class T> -inline +AI_FORCE_INLINE IOStreamBuffer<T>::~IOStreamBuffer() { // empty } template<class T> -inline +AI_FORCE_INLINE bool IOStreamBuffer<T>::open( IOStream *stream ) { // file still opened! if ( nullptr != m_stream ) { @@ -174,7 +179,7 @@ bool IOStreamBuffer<T>::open( IOStream *stream ) { } template<class T> -inline +AI_FORCE_INLINE bool IOStreamBuffer<T>::close() { if ( nullptr == m_stream ) { return false; @@ -192,19 +197,19 @@ bool IOStreamBuffer<T>::close() { } template<class T> -inline +AI_FORCE_INLINE size_t IOStreamBuffer<T>::size() const { return m_filesize; } template<class T> -inline +AI_FORCE_INLINE size_t IOStreamBuffer<T>::cacheSize() const { return m_cacheSize; } template<class T> -inline +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 ); @@ -222,25 +227,25 @@ bool IOStreamBuffer<T>::readNextBlock() { } template<class T> -inline +AI_FORCE_INLINE size_t IOStreamBuffer<T>::getNumBlocks() const { return m_numBlocks; } template<class T> -inline +AI_FORCE_INLINE size_t IOStreamBuffer<T>::getCurrentBlockIndex() const { return m_blockIdx; } template<class T> -inline +AI_FORCE_INLINE size_t IOStreamBuffer<T>::getFilePos() const { return m_filePos; } template<class T> -inline +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 ) { @@ -289,13 +294,13 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT return true; } -static inline +static AI_FORCE_INLINE bool isEndOfCache( size_t pos, size_t cacheSize ) { return ( pos == cacheSize ); } template<class T> -inline +AI_FORCE_INLINE bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) { buffer.resize(m_cacheSize); if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) { @@ -335,7 +340,7 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) { } template<class T> -inline +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 ) { @@ -353,3 +358,5 @@ bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) { } } // !ns Assimp + +#endif // AI_IOSTREAMBUFFER_H_INC diff --git a/thirdparty/assimp/include/assimp/IOSystem.hpp b/thirdparty/assimp/include/assimp/IOSystem.hpp index 78139c2839..f1fb3b0c27 100644 --- a/thirdparty/assimp/include/assimp/IOSystem.hpp +++ b/thirdparty/assimp/include/assimp/IOSystem.hpp @@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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. diff --git a/thirdparty/assimp/include/assimp/Importer.hpp b/thirdparty/assimp/include/assimp/Importer.hpp index 4941df4122..bf449a9a25 100644 --- a/thirdparty/assimp/include/assimp/Importer.hpp +++ b/thirdparty/assimp/include/assimp/Importer.hpp @@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 diff --git a/thirdparty/assimp/include/assimp/LineSplitter.h b/thirdparty/assimp/include/assimp/LineSplitter.h index 4afe45b92a..6c1097bb6d 100644 --- a/thirdparty/assimp/include/assimp/LineSplitter.h +++ b/thirdparty/assimp/include/assimp/LineSplitter.h @@ -48,9 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef INCLUDED_LINE_SPLITTER_H #define INCLUDED_LINE_SPLITTER_H +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include <stdexcept> -#include "StreamReader.h" -#include "ParsingUtils.h" +#include <assimp/StreamReader.h> +#include <assimp/ParsingUtils.h> namespace Assimp { @@ -140,7 +144,7 @@ private: bool mSwallow, mSkip_empty_lines, mTrim; }; -inline +AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) : mIdx(0) , mCur() @@ -153,12 +157,12 @@ LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool t mIdx = 0; } -inline +AI_FORCE_INLINE LineSplitter::~LineSplitter() { // empty } -inline +AI_FORCE_INLINE LineSplitter& LineSplitter::operator++() { if (mSwallow) { mSwallow = false; @@ -199,12 +203,12 @@ LineSplitter& LineSplitter::operator++() { return *this; } -inline +AI_FORCE_INLINE LineSplitter &LineSplitter::operator++(int) { return ++(*this); } -inline +AI_FORCE_INLINE const char *LineSplitter::operator[] (size_t idx) const { const char* s = operator->()->c_str(); @@ -222,7 +226,7 @@ const char *LineSplitter::operator[] (size_t idx) const { } template <size_t N> -inline +AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const { const char* s = operator->()->c_str(); @@ -238,44 +242,44 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const { } } -inline +AI_FORCE_INLINE const std::string* LineSplitter::operator -> () const { return &mCur; } -inline +AI_FORCE_INLINE std::string LineSplitter::operator* () const { return mCur; } -inline +AI_FORCE_INLINE LineSplitter::operator bool() const { return mStream.GetRemainingSize() > 0; } -inline +AI_FORCE_INLINE LineSplitter::operator line_idx() const { return mIdx; } -inline +AI_FORCE_INLINE LineSplitter::line_idx LineSplitter::get_index() const { return mIdx; } -inline +AI_FORCE_INLINE StreamReaderLE &LineSplitter::get_stream() { return mStream; } -inline +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()); } -inline +AI_FORCE_INLINE void LineSplitter::swallow_next_increment() { mSwallow = true; } diff --git a/thirdparty/assimp/include/assimp/LogAux.h b/thirdparty/assimp/include/assimp/LogAux.h index 558485272e..bcead78dd3 100644 --- a/thirdparty/assimp/include/assimp/LogAux.h +++ b/thirdparty/assimp/include/assimp/LogAux.h @@ -43,9 +43,14 @@ 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> diff --git a/thirdparty/assimp/include/assimp/Macros.h b/thirdparty/assimp/include/assimp/Macros.h deleted file mode 100644 index 6515303372..0000000000 --- a/thirdparty/assimp/include/assimp/Macros.h +++ /dev/null @@ -1,49 +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. ---------------------------------------------------------------------------- -*/ - -/* 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 - diff --git a/thirdparty/assimp/include/assimp/MathFunctions.h b/thirdparty/assimp/include/assimp/MathFunctions.h index cb3b696076..b6c5872a72 100644 --- a/thirdparty/assimp/include/assimp/MathFunctions.h +++ b/thirdparty/assimp/include/assimp/MathFunctions.h @@ -39,22 +39,28 @@ 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 the math functions (gcd and lcm) +* @brief Implementation of math utility functions. * - * Copied from BoostWorkaround/math - */ +*/ + +#include <limits> namespace Assimp { namespace Math { // TODO: use binary GCD for unsigned integers .... template < typename IntegerType > -IntegerType gcd( IntegerType a, IntegerType b ) -{ +inline +IntegerType gcd( IntegerType a, IntegerType b ) { const IntegerType zero = (IntegerType)0; - while ( true ) - { + while ( true ) { if ( a == zero ) return b; b %= a; @@ -66,12 +72,19 @@ IntegerType gcd( IntegerType a, IntegerType b ) } template < typename IntegerType > -IntegerType lcm( IntegerType a, IntegerType b ) -{ +inline +IntegerType lcm( IntegerType a, IntegerType b ) { const IntegerType t = gcd (a,b); - if (!t)return t; + 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 index c522787184..5598d4fc5f 100644 --- a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h +++ b/thirdparty/assimp/include/assimp/MemoryIOWrapper.h @@ -42,12 +42,18 @@ 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 { diff --git a/thirdparty/assimp/include/assimp/ParsingUtils.h b/thirdparty/assimp/include/assimp/ParsingUtils.h index 6b9574fc67..3025601246 100644 --- a/thirdparty/assimp/include/assimp/ParsingUtils.h +++ b/thirdparty/assimp/include/assimp/ParsingUtils.h @@ -44,11 +44,16 @@ 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 -#include "StringComparison.h" -#include "StringUtils.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/StringComparison.h> +#include <assimp/StringUtils.h> #include <assimp/defs.h> namespace Assimp { diff --git a/thirdparty/assimp/include/assimp/Profiler.h b/thirdparty/assimp/include/assimp/Profiler.h index 6ff9d41c0a..624029be99 100644 --- a/thirdparty/assimp/include/assimp/Profiler.h +++ b/thirdparty/assimp/include/assimp/Profiler.h @@ -43,12 +43,17 @@ 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 */ -#ifndef INCLUDED_PROFILER_H -#define INCLUDED_PROFILER_H +#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 "TinyFormatter.h" +#include <assimp/TinyFormatter.h> #include <map> @@ -67,7 +72,6 @@ public: // empty } -public: /** Start a named timer */ void BeginRegion(const std::string& region) { @@ -95,5 +99,5 @@ private: } } -#endif +#endif // AI_INCLUDED_PROFILER_H diff --git a/thirdparty/assimp/include/assimp/ProgressHandler.hpp b/thirdparty/assimp/include/assimp/ProgressHandler.hpp index 4e47f1d0a6..8991a64618 100644 --- a/thirdparty/assimp/include/assimp/ProgressHandler.hpp +++ b/thirdparty/assimp/include/assimp/ProgressHandler.hpp @@ -47,9 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_PROGRESSHANDLER_H_INC #define AI_PROGRESSHANDLER_H_INC -#include "types.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/types.h> -namespace Assimp { +namespace Assimp { // ------------------------------------------------------------------------------------ /** @brief CPP-API: Abstract interface for custom progress report receivers. diff --git a/thirdparty/assimp/include/assimp/RemoveComments.h b/thirdparty/assimp/include/assimp/RemoveComments.h index 404b496719..f129420535 100644 --- a/thirdparty/assimp/include/assimp/RemoveComments.h +++ b/thirdparty/assimp/include/assimp/RemoveComments.h @@ -4,7 +4,6 @@ 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, @@ -43,9 +42,13 @@ 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> @@ -58,8 +61,7 @@ namespace Assimp { * to those in C or C++ so this code has been moved to a separate * module. */ -class ASSIMP_API CommentRemover -{ +class ASSIMP_API CommentRemover { // class cannot be instanced CommentRemover() {} diff --git a/thirdparty/assimp/include/assimp/SGSpatialSort.h b/thirdparty/assimp/include/assimp/SGSpatialSort.h index 5b4f3f41f2..fdb5ce8174 100644 --- a/thirdparty/assimp/include/assimp/SGSpatialSort.h +++ b/thirdparty/assimp/include/assimp/SGSpatialSort.h @@ -42,9 +42,14 @@ 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> diff --git a/thirdparty/assimp/include/assimp/SceneCombiner.h b/thirdparty/assimp/include/assimp/SceneCombiner.h index 679a2acea4..0683c1e052 100644 --- a/thirdparty/assimp/include/assimp/SceneCombiner.h +++ b/thirdparty/assimp/include/assimp/SceneCombiner.h @@ -43,17 +43,22 @@ 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; @@ -65,8 +70,10 @@ struct aiLight; struct aiMetadata; struct aiBone; struct aiMesh; +struct aiAnimMesh; struct aiAnimation; struct aiNodeAnim; +struct aiMeshMorphAnim; namespace Assimp { @@ -363,6 +370,7 @@ public: 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); @@ -370,6 +378,7 @@ public: 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 diff --git a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h index f9b8d9f55c..ad979a33fa 100644 --- a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h +++ b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h @@ -47,9 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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> diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.h b/thirdparty/assimp/include/assimp/SmoothingGroups.h index 92d65cea02..c1a93947f1 100644 --- a/thirdparty/assimp/include/assimp/SmoothingGroups.h +++ b/thirdparty/assimp/include/assimp/SmoothingGroups.h @@ -43,10 +43,16 @@ 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> diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.inl b/thirdparty/assimp/include/assimp/SmoothingGroups.inl index 84ea4a1b00..37ea083dbe 100644 --- a/thirdparty/assimp/include/assimp/SmoothingGroups.inl +++ b/thirdparty/assimp/include/assimp/SmoothingGroups.inl @@ -41,13 +41,16 @@ 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 -// internal headers +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include <assimp/SGSpatialSort.h> -// CRT header #include <algorithm> using namespace Assimp; diff --git a/thirdparty/assimp/include/assimp/SpatialSort.h b/thirdparty/assimp/include/assimp/SpatialSort.h index 61b345bcbf..9f93543150 100644 --- a/thirdparty/assimp/include/assimp/SpatialSort.h +++ b/thirdparty/assimp/include/assimp/SpatialSort.h @@ -41,9 +41,14 @@ 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> diff --git a/thirdparty/assimp/include/assimp/StandardShapes.h b/thirdparty/assimp/include/assimp/StandardShapes.h index 3791569b83..c594cb63f4 100644 --- a/thirdparty/assimp/include/assimp/StandardShapes.h +++ b/thirdparty/assimp/include/assimp/StandardShapes.h @@ -41,11 +41,16 @@ 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 cylnders, cones, spheres .. + * 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> diff --git a/thirdparty/assimp/include/assimp/StreamReader.h b/thirdparty/assimp/include/assimp/StreamReader.h index 9116c14261..cb24f1595b 100644 --- a/thirdparty/assimp/include/assimp/StreamReader.h +++ b/thirdparty/assimp/include/assimp/StreamReader.h @@ -44,15 +44,19 @@ 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 "ByteSwapper.h" -#include "Exceptional.h" #include <memory> namespace Assimp { diff --git a/thirdparty/assimp/include/assimp/StreamWriter.h b/thirdparty/assimp/include/assimp/StreamWriter.h index c7cf6c0d74..489e8adfe3 100644 --- a/thirdparty/assimp/include/assimp/StreamWriter.h +++ b/thirdparty/assimp/include/assimp/StreamWriter.h @@ -43,11 +43,15 @@ 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 -#include "ByteSwapper.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/ByteSwapper.h> #include <assimp/IOStream.hpp> #include <memory> diff --git a/thirdparty/assimp/include/assimp/StringComparison.h b/thirdparty/assimp/include/assimp/StringComparison.h index 8acef277b9..d3ca3e9714 100644 --- a/thirdparty/assimp/include/assimp/StringComparison.h +++ b/thirdparty/assimp/include/assimp/StringComparison.h @@ -49,12 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 "StringComparison.h" +#include <assimp/StringComparison.h> #include <string.h> #include <stdint.h> diff --git a/thirdparty/assimp/include/assimp/StringUtils.h b/thirdparty/assimp/include/assimp/StringUtils.h index d68b7fa479..af481f819e 100644 --- a/thirdparty/assimp/include/assimp/StringUtils.h +++ b/thirdparty/assimp/include/assimp/StringUtils.h @@ -39,9 +39,14 @@ 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> diff --git a/thirdparty/assimp/include/assimp/Subdivision.h b/thirdparty/assimp/include/assimp/Subdivision.h index 43feb73b30..e9450267ec 100644 --- a/thirdparty/assimp/include/assimp/Subdivision.h +++ b/thirdparty/assimp/include/assimp/Subdivision.h @@ -45,7 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_SUBDISIVION_H_INC #define AI_SUBDISIVION_H_INC -#include <cstddef> +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include <assimp/types.h> struct aiMesh; diff --git a/thirdparty/assimp/include/assimp/TinyFormatter.h b/thirdparty/assimp/include/assimp/TinyFormatter.h index 1226b482e6..6227e42c52 100644 --- a/thirdparty/assimp/include/assimp/TinyFormatter.h +++ b/thirdparty/assimp/include/assimp/TinyFormatter.h @@ -45,9 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 { @@ -65,24 +70,15 @@ namespace Formatter { * @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; - + 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() {} + basic_formatter() { + // empty + } /* Allow basic_formatter<T>'s to be used almost interchangeably * with std::(w)string or const (w)char* arguments because the @@ -104,14 +100,10 @@ public: } #endif - -public: - 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 diff --git a/thirdparty/assimp/include/assimp/Vertex.h b/thirdparty/assimp/include/assimp/Vertex.h index 2a7f0256ad..5e63db5fe4 100644 --- a/thirdparty/assimp/include/assimp/Vertex.h +++ b/thirdparty/assimp/include/assimp/Vertex.h @@ -47,12 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 { @@ -91,23 +97,14 @@ namespace Assimp { * 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 -{ +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 * (const Vertex&,ai_real); friend Vertex operator / (const Vertex&,ai_real); - -// friend Vertex operator + (ai_real, const Vertex&); -// friend Vertex operator - (ai_real, const Vertex&); friend Vertex operator * (ai_real, const Vertex&); -// friend Vertex operator / (ai_real, const Vertex&); public: - Vertex() {} // ---------------------------------------------------------------------------- @@ -158,8 +155,6 @@ public: } } -public: - Vertex& operator += (const Vertex& v) { *this = *this+v; return *this; @@ -170,18 +165,6 @@ public: return *this; } - -/* - Vertex& operator += (ai_real 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; @@ -192,12 +175,9 @@ public: return *this; } -public: - // ---------------------------------------------------------------------------- /** Convert back to non-interleaved storage */ void SortBack(aiMesh* out, unsigned int idx) const { - ai_assert(idx<out->mNumVertices); out->mVertices[idx] = position; @@ -291,8 +271,6 @@ public: 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); @@ -302,19 +280,6 @@ 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::plus>(v0,f); -} - -AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) { - return Vertex::BinaryOp<Intern::minus>(v0,f); -} - -*/ - AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) { return Vertex::BinaryOp<Intern::multiplies>(v0,f); } @@ -323,26 +288,10 @@ 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::plus>(f,v0); -} - -AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) { - return Vertex::BinaryOp<Intern::minus>(f,v0); -} -*/ - AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) { return Vertex::BinaryOp<Intern::multiplies>(f,v0); } -/* -AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) { - return Vertex::BinaryOp<Intern::divides>(f,v0); } -*/ -} -#endif +#endif // AI_VERTEX_H_INC diff --git a/thirdparty/assimp/include/assimp/XMLTools.h b/thirdparty/assimp/include/assimp/XMLTools.h index b0d3276873..95f12cdebf 100644 --- a/thirdparty/assimp/include/assimp/XMLTools.h +++ b/thirdparty/assimp/include/assimp/XMLTools.h @@ -40,9 +40,14 @@ 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 { diff --git a/thirdparty/assimp/include/assimp/aabb.h b/thirdparty/assimp/include/assimp/aabb.h index a20f317424..83bb62256b 100644 --- a/thirdparty/assimp/include/assimp/aabb.h +++ b/thirdparty/assimp/include/assimp/aabb.h @@ -5,8 +5,6 @@ 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, @@ -45,6 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_AABB_H_INC #define AI_AABB_H_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include <assimp/vector3.h> struct aiAABB { @@ -69,8 +71,9 @@ struct aiAABB { // empty } -#endif +#endif // __cplusplus + }; -#endif +#endif // AI_AABB_H_INC diff --git a/thirdparty/assimp/include/assimp/ai_assert.h b/thirdparty/assimp/include/assimp/ai_assert.h index e5de5d3f36..2b32b01d3e 100644 --- a/thirdparty/assimp/include/assimp/ai_assert.h +++ b/thirdparty/assimp/include/assimp/ai_assert.h @@ -44,6 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 ) diff --git a/thirdparty/assimp/include/assimp/anim.h b/thirdparty/assimp/include/assimp/anim.h index 02e92739ec..e208b11adb 100644 --- a/thirdparty/assimp/include/assimp/anim.h +++ b/thirdparty/assimp/include/assimp/anim.h @@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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> diff --git a/thirdparty/assimp/include/assimp/camera.h b/thirdparty/assimp/include/assimp/camera.h index e573eea5d1..adb749ff59 100644 --- a/thirdparty/assimp/include/assimp/camera.h +++ b/thirdparty/assimp/include/assimp/camera.h @@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_CAMERA_H_INC #define AI_CAMERA_H_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include "types.h" #ifdef __cplusplus @@ -113,7 +117,6 @@ struct aiCamera */ C_STRUCT aiVector3D mPosition; - /** 'Up' - vector of the camera coordinate system relative to * the coordinate space defined by the corresponding node. * @@ -134,7 +137,6 @@ struct aiCamera */ C_STRUCT aiVector3D mLookAt; - /** Half horizontal field of view angle, in radians. * * The field of view angle is the angle between the center diff --git a/thirdparty/assimp/include/assimp/cexport.h b/thirdparty/assimp/include/assimp/cexport.h index 1d62dc26b3..cbc0253d50 100644 --- a/thirdparty/assimp/include/assimp/cexport.h +++ b/thirdparty/assimp/include/assimp/cexport.h @@ -3,7 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2011, assimp team +Copyright (c) 2006-2019, assimp team All rights reserved. @@ -46,6 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 diff --git a/thirdparty/assimp/include/assimp/cfileio.h b/thirdparty/assimp/include/assimp/cfileio.h index 8f7ca45469..be90999d87 100644 --- a/thirdparty/assimp/include/assimp/cfileio.h +++ b/thirdparty/assimp/include/assimp/cfileio.h @@ -48,10 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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; diff --git a/thirdparty/assimp/include/assimp/cimport.h b/thirdparty/assimp/include/assimp/cimport.h index dbd10f1370..66b1c9a174 100644 --- a/thirdparty/assimp/include/assimp/cimport.h +++ b/thirdparty/assimp/include/assimp/cimport.h @@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_ASSIMP_H_INC #define AI_ASSIMP_H_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include <assimp/types.h> -#include "importerdesc.h" +#include <assimp/importerdesc.h> #ifdef __cplusplus extern "C" { diff --git a/thirdparty/assimp/include/assimp/color4.h b/thirdparty/assimp/include/assimp/color4.h index 3c97c8eda2..fa86128f4f 100644 --- a/thirdparty/assimp/include/assimp/color4.h +++ b/thirdparty/assimp/include/assimp/color4.h @@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_COLOR4D_H_INC #define AI_COLOR4D_H_INC -#include "defs.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/defs.h> #ifdef __cplusplus @@ -56,8 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * alpha component. Color values range from 0 to 1. */ // ---------------------------------------------------------------------------------- template <typename TReal> -class aiColor4t -{ +class aiColor4t { public: aiColor4t() AI_NO_EXCEPT : r(), g(), b(), a() {} aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a) @@ -65,14 +68,12 @@ public: explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {} aiColor4t (const aiColor4t& o) = default; -public: // combined operators const aiColor4t& operator += (const aiColor4t& o); const aiColor4t& operator -= (const aiColor4t& o); const aiColor4t& operator *= (TReal f); const aiColor4t& operator /= (TReal f); -public: // comparison bool operator == (const aiColor4t& other) const; bool operator != (const aiColor4t& other) const; @@ -85,8 +86,6 @@ public: /** check whether a color is (close to) black */ inline bool IsBlack() const; -public: - // Red, green, blue and alpha color values TReal r, g, b, a; }; // !struct aiColor4D diff --git a/thirdparty/assimp/include/assimp/color4.inl b/thirdparty/assimp/include/assimp/color4.inl index afa53dcb5b..d4a2a98109 100644 --- a/thirdparty/assimp/include/assimp/color4.inl +++ b/thirdparty/assimp/include/assimp/color4.inl @@ -48,36 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_COLOR4D_INL_INC #define AI_COLOR4D_INL_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #ifdef __cplusplus -#include "color4.h" +#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; +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; +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; +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; +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 { +AI_FORCE_INLINE +TReal aiColor4t<TReal>::operator[](unsigned int i) const { switch ( i ) { case 0: return r; @@ -94,7 +119,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const { } // ------------------------------------------------------------------------------------------------ template <typename TReal> -AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) { +AI_FORCE_INLINE +TReal& aiColor4t<TReal>::operator[](unsigned int i) { switch ( i ) { case 0: return r; @@ -111,17 +137,20 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) { } // ------------------------------------------------------------------------------------------------ template <typename TReal> -AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const { +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 { +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 { +AI_FORCE_INLINE +bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const { return r < other.r || ( r == other.r && ( g < other.g || ( @@ -136,14 +165,17 @@ AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) ) ); } + // ------------------------------------------------------------------------------------------------ template <typename TReal> -AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { +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) { +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); } // ------------------------------------------------------------------------------------------------ @@ -153,53 +185,63 @@ AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const a } // ------------------------------------------------------------------------------------------------ template <typename TReal> -AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { +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) { +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) { +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) { +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) { +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) { +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) { +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) { +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) { +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> -inline bool aiColor4t<TReal> :: IsBlack() const { +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; diff --git a/thirdparty/assimp/include/assimp/defs.h b/thirdparty/assimp/include/assimp/defs.h index 05a5e3fd4b..6f2f8ae88b 100644 --- a/thirdparty/assimp/include/assimp/defs.h +++ b/thirdparty/assimp/include/assimp/defs.h @@ -5,8 +5,6 @@ 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, @@ -50,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_DEFINES_H_INC #define AI_DEFINES_H_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #include <assimp/config.h> ////////////////////////////////////////////////////////////////////////// @@ -126,16 +128,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * GENBOUNDINGBOXES */ ////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER +#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) -# pragma warning (disable : 4251) ////////////////////////////////////////////////////////////////////////// /* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in @@ -148,7 +148,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 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 @@ -156,17 +168,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* 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 ASSIMP_API __attribute__ ((visibility("default"))) -# define ASSIMP_API_WINONLY # define AI_FORCE_INLINE inline #endif // (defined _MSC_VER) @@ -291,9 +298,10 @@ static const ai_real ai_epsilon = (ai_real) 0.00001; #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 +/** + * 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)) @@ -307,4 +315,13 @@ static const ai_real ai_epsilon = (ai_real) 0.00001; # 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 index 62ea969e97..6e9a1bba7a 100644 --- a/thirdparty/assimp/include/assimp/fast_atof.h +++ b/thirdparty/assimp/include/assimp/fast_atof.h @@ -13,10 +13,14 @@ // 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> diff --git a/thirdparty/assimp/include/assimp/importerdesc.h b/thirdparty/assimp/include/assimp/importerdesc.h index 36e387f011..0a6919c1ae 100644 --- a/thirdparty/assimp/include/assimp/importerdesc.h +++ b/thirdparty/assimp/include/assimp/importerdesc.h @@ -48,11 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 -{ +enum aiImporterFlags { /** Indicates that there is a textual encoding of the * file format; and that it is supported.*/ aiImporterFlags_SupportTextFlavour = 0x1, @@ -87,8 +90,7 @@ enum aiImporterFlags * 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 -{ +struct aiImporterDesc { /** Full name of the importer (i.e. Blender3D importer)*/ const char* mName; diff --git a/thirdparty/assimp/include/assimp/light.h b/thirdparty/assimp/include/assimp/light.h index 1667cfb8c1..bdb2368c4f 100644 --- a/thirdparty/assimp/include/assimp/light.h +++ b/thirdparty/assimp/include/assimp/light.h @@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_LIGHT_H_INC #define AI_LIGHT_H_INC -#include "types.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/types.h> #ifdef __cplusplus extern "C" { diff --git a/thirdparty/assimp/include/assimp/material.h b/thirdparty/assimp/include/assimp/material.h index 206eb2a2b0..19a7c69709 100644 --- a/thirdparty/assimp/include/assimp/material.h +++ b/thirdparty/assimp/include/assimp/material.h @@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_MATERIAL_H_INC #define AI_MATERIAL_H_INC -#include "types.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/types.h> #ifdef __cplusplus extern "C" { diff --git a/thirdparty/assimp/include/assimp/material.inl b/thirdparty/assimp/include/assimp/material.inl index b05d6af6c3..8ae6b88d3e 100644 --- a/thirdparty/assimp/include/assimp/material.inl +++ b/thirdparty/assimp/include/assimp/material.inl @@ -49,14 +49,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_MATERIAL_INL_INC #define AI_MATERIAL_INL_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + // --------------------------------------------------------------------------- -inline aiPropertyTypeInfo ai_real_to_property_type_info(float) -{ +AI_FORCE_INLINE +aiPropertyTypeInfo ai_real_to_property_type_info(float) { return aiPTI_Float; } -inline aiPropertyTypeInfo ai_real_to_property_type_info(double) -{ +AI_FORCE_INLINE +aiPropertyTypeInfo ai_real_to_property_type_info(double) { return aiPTI_Double; } // --------------------------------------------------------------------------- @@ -64,30 +68,30 @@ inline aiPropertyTypeInfo ai_real_to_property_type_info(double) //! @cond never // --------------------------------------------------------------------------- -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 -{ +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); } // --------------------------------------------------------------------------- -inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const -{ +AI_FORCE_INLINE +unsigned int aiMaterial::GetTextureCount(aiTextureType type) const { return ::aiGetMaterialTextureCount(this,type); } // --------------------------------------------------------------------------- template <typename Type> -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx, Type* pOut, - unsigned int* pMax) const -{ +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; @@ -114,9 +118,9 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, // --------------------------------------------------------------------------- template <typename Type> -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,Type& pOut) const -{ +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); @@ -136,60 +140,56 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,ai_real* pOut, - unsigned int* pMax) const -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,int* pOut, - unsigned int* pMax) const -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,ai_real& pOut) const -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,int& pOut) const -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiColor4D& pOut) const -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiColor3D& pOut) const -{ +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; } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiString& pOut) const -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, - unsigned int idx,aiUVTransform& pOut) const -{ +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, @@ -204,84 +204,83 @@ aiReturn aiMaterial::AddProperty (const TYPE* pInput, } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const float* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const double* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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)); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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)); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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)); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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)); } // --------------------------------------------------------------------------- -inline aiReturn aiMaterial::AddProperty(const int* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -296,12 +295,12 @@ inline aiReturn aiMaterial::AddProperty(const int* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<float>(const float* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -309,12 +308,12 @@ inline aiReturn aiMaterial::AddProperty<float>(const float* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<double>(const double* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -322,12 +321,12 @@ inline aiReturn aiMaterial::AddProperty<double>(const double* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -335,12 +334,12 @@ inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInp // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -348,12 +347,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -361,12 +360,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); @@ -374,12 +373,12 @@ inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<int>(const int* pInput, - const unsigned int pNumValues, - const char* pKey, - unsigned int type, - unsigned int index) -{ +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); diff --git a/thirdparty/assimp/include/assimp/matrix3x3.h b/thirdparty/assimp/include/assimp/matrix3x3.h index 22b69561ff..2c26cf92bb 100644 --- a/thirdparty/assimp/include/assimp/matrix3x3.h +++ b/thirdparty/assimp/include/assimp/matrix3x3.h @@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_MATRIX3X3_H_INC #define AI_MATRIX3X3_H_INC -#include "defs.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/defs.h> #ifdef __cplusplus @@ -65,10 +69,8 @@ template <typename T> class aiVector2t; * defined thereby. */ template <typename TReal> -class aiMatrix3x3t -{ +class aiMatrix3x3t { public: - aiMatrix3x3t() AI_NO_EXCEPT : a1(static_cast<TReal>(1.0f)), a2(), a3(), b1(), b2(static_cast<TReal>(1.0f)), b3(), @@ -82,8 +84,6 @@ public: c1(_c1), c2(_c2), c3(_c3) {} -public: - // matrix multiplication. aiMatrix3x3t& operator *= (const aiMatrix3x3t& m); aiMatrix3x3t operator * (const aiMatrix3x3t& m) const; @@ -101,8 +101,6 @@ public: template <typename TOther> operator aiMatrix3x3t<TOther> () const; -public: - // ------------------------------------------------------------------- /** @brief Construction from a 4x4 matrix. The remaining parts * of the matrix are ignored. @@ -122,7 +120,6 @@ public: aiMatrix3x3t& Inverse(); TReal Determinant() const; -public: // ------------------------------------------------------------------- /** @brief Returns a rotation matrix for a rotation around z * @param a Rotation angle, in radians diff --git a/thirdparty/assimp/include/assimp/matrix3x3.inl b/thirdparty/assimp/include/assimp/matrix3x3.inl index d9d45a3e92..1ce8c9691c 100644 --- a/thirdparty/assimp/include/assimp/matrix3x3.inl +++ b/thirdparty/assimp/include/assimp/matrix3x3.inl @@ -48,10 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_MATRIX3X3_INL_INC #define AI_MATRIX3X3_INL_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #ifdef __cplusplus -#include "matrix3x3.h" +#include <assimp/matrix3x3.h> +#include <assimp/matrix4x4.h> -#include "matrix4x4.h" #include <algorithm> #include <cmath> #include <limits> @@ -59,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ------------------------------------------------------------------------------------------------ // Construction from a 4x4 matrix. The remaining parts of the matrix are ignored. template <typename TReal> -inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix) -{ +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; @@ -68,8 +72,8 @@ inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix) // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m) -{ +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, @@ -85,8 +89,7 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t // ------------------------------------------------------------------------------------------------ template <typename TReal> template <typename TOther> -aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const -{ +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)); @@ -94,8 +97,8 @@ aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const -{ +AI_FORCE_INLINE +aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const { aiMatrix3x3t<TReal> temp( *this); temp *= m; return temp; @@ -103,7 +106,8 @@ inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TR // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) { +AI_FORCE_INLINE +TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) { switch ( p_iIndex ) { case 0: return &a1; @@ -119,7 +123,8 @@ inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) { // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const { +AI_FORCE_INLINE +const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const { switch ( p_iIndex ) { case 0: return &a1; @@ -135,8 +140,8 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const -{ +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; @@ -144,14 +149,15 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const -{ +AI_FORCE_INLINE +bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const { return !(*this == m); } // --------------------------------------------------------------------------- template<typename TReal> -inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { +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 && @@ -166,8 +172,8 @@ inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() -{ +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); @@ -177,15 +183,15 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() // ---------------------------------------------------------------------------------------- template <typename TReal> -inline TReal aiMatrix3x3t<TReal>::Determinant() const -{ +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> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() -{ +AI_FORCE_INLINE +aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() { // Compute the reciprocal determinant TReal det = Determinant(); if(det == static_cast<TReal>(0.0)) @@ -219,8 +225,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out) -{ +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; @@ -234,8 +240,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t // ------------------------------------------------------------------------------------------------ // Returns a rotation matrix for a rotation around an arbitrary axis. template <typename TReal> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out) -{ +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; @@ -249,8 +255,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVect // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out) -{ +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; @@ -268,9 +274,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<T */ // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, - const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx) -{ +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; @@ -352,6 +357,5 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<T 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 index 046bb535f2..8fc216f669 100644 --- a/thirdparty/assimp/include/assimp/matrix4x4.h +++ b/thirdparty/assimp/include/assimp/matrix4x4.h @@ -47,8 +47,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_MATRIX4X4_H_INC #define AI_MATRIX4X4_H_INC -#include "vector3.h" -#include "defs.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/vector3.h> +#include <assimp/defs.h> #ifdef __cplusplus @@ -66,8 +70,7 @@ template<typename TReal> class aiQuaterniont; * defined thereby. */ template<typename TReal> -class aiMatrix4x4t -{ +class aiMatrix4x4t { public: /** set to identity */ @@ -91,8 +94,6 @@ public: aiMatrix4x4t(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position); -public: - // array access operators /** @fn TReal* operator[] (unsigned int p_iIndex) * @param [in] p_iIndex - index of the row. @@ -120,8 +121,6 @@ public: template <typename TOther> operator aiMatrix4x4t<TOther> () const; -public: - // ------------------------------------------------------------------- /** @brief Transpose the matrix */ aiMatrix4x4t& Transpose(); @@ -182,7 +181,6 @@ public: 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 @@ -192,7 +190,6 @@ public: aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z); aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb); -public: // ------------------------------------------------------------------- /** @brief Returns a rotation matrix for a rotation around the x axis * @param a Rotation angle, in radians @@ -256,7 +253,6 @@ public: static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from, const aiVector3t<TReal>& to, aiMatrix4x4t& out); -public: TReal a1, a2, a3, a4; TReal b1, b2, b3, b4; TReal c1, c2, c3, c4; diff --git a/thirdparty/assimp/include/assimp/matrix4x4.inl b/thirdparty/assimp/include/assimp/matrix4x4.inl index ebc67a06ec..84079974f7 100644 --- a/thirdparty/assimp/include/assimp/matrix4x4.inl +++ b/thirdparty/assimp/include/assimp/matrix4x4.inl @@ -5,8 +5,6 @@ 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, @@ -53,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "matrix4x4.h" #include "matrix3x3.h" #include "quaternion.h" +#include "MathFunctions.h" #include <algorithm> #include <limits> @@ -61,12 +60,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------------------- 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) -{ - + 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 } // ---------------------------------------------------------------------------------------- @@ -75,19 +73,17 @@ 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) -{ - + 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 -{ +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), @@ -97,8 +93,8 @@ aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) -{ +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); @@ -107,8 +103,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position) -{ +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(); @@ -135,8 +131,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, cons // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) -{ +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, @@ -159,8 +155,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const -{ +AI_FORCE_INLINE aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const { aiMatrix4x4t<TReal> temp( a1 * aFloat, a2 * aFloat, @@ -183,8 +178,8 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const { aiMatrix4x4t<TReal> temp( m.a1 + a1, m.a2 + a2, @@ -207,18 +202,16 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TR // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const { aiMatrix4x4t<TReal> temp( *this); temp *= m; return temp; } - // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() -{ +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); @@ -229,11 +222,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() return *this; } - // ---------------------------------------------------------------------------------------- template <typename TReal> -inline TReal aiMatrix4x4t<TReal>::Determinant() const -{ +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 @@ -244,8 +236,8 @@ inline TReal aiMatrix4x4t<TReal>::Determinant() const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() { // Compute the reciprocal determinant const TReal det = Determinant(); if(det == static_cast<TReal>(0.0)) @@ -289,9 +281,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() // ---------------------------------------------------------------------------------------- template <typename TReal> -inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) { +AI_FORCE_INLINE +TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) { if (p_iIndex > 3) { - return NULL; + return nullptr; } switch ( p_iIndex ) { case 0: @@ -310,9 +303,10 @@ inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) { // ---------------------------------------------------------------------------------------- template <typename TReal> -inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const { +AI_FORCE_INLINE +const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const { if (p_iIndex > 3) { - return NULL; + return nullptr; } switch ( p_iIndex ) { @@ -332,8 +326,8 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const -{ +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 && @@ -342,14 +336,15 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const -{ +AI_FORCE_INLINE +bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const { return !(*this == m); } // --------------------------------------------------------------------------- template<typename TReal> -inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { +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 && @@ -401,13 +396,10 @@ inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil \ do {} while(false) - - - template <typename TReal> -inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation, - aiVector3t<TReal>& pPosition) const -{ +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 @@ -420,8 +412,8 @@ inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuate } template <typename TReal> -inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const -{ +AI_FORCE_INLINE +void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const { ASSIMP_MATRIX4_4_DECOMPOSE_PART; /* @@ -442,7 +434,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector */ // Use a small epsilon to solve floating-point inaccuracies - const TReal epsilon = 10e-3f; + const TReal epsilon = Assimp::Math::getEpsilon<TReal>(); pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY. @@ -475,10 +467,10 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector #undef ASSIMP_MATRIX4_4_DECOMPOSE_PART template <typename TReal> -inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, - aiVector3t<TReal>& pPosition) const -{ -aiQuaterniont<TReal> pRotation; +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(); @@ -500,9 +492,9 @@ aiQuaterniont<TReal> pRotation; // ---------------------------------------------------------------------------------------- template <typename TReal> -inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation, - aiVector3t<TReal>& position) const -{ +AI_FORCE_INLINE +void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation, + aiVector3t<TReal>& position) const { const aiMatrix4x4t<TReal>& _this = *this; // extract translation @@ -516,15 +508,15 @@ inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotat // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) { return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z); } // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) { aiMatrix4x4t<TReal>& _this = *this; TReal cx = std::cos(x); @@ -552,8 +544,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TRe // ---------------------------------------------------------------------------------------- template <typename TReal> -inline bool aiMatrix4x4t<TReal>::IsIdentity() const -{ +AI_FORCE_INLINE +bool aiMatrix4x4t<TReal>::IsIdentity() const { // Use a small epsilon to solve floating-point inaccuracies const static TReal epsilon = 10e-3f; @@ -577,8 +569,8 @@ inline bool aiMatrix4x4t<TReal>::IsIdentity() const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) { /* | 1 0 0 0 | M = | 0 cos(A) -sin(A) 0 | @@ -592,8 +584,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) -{ +AI_FORCE_INLINE +aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) { /* | cos(A) 0 sin(A) 0 | M = | 0 1 0 0 | @@ -608,8 +600,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) -{ +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 | @@ -624,26 +616,25 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t // ---------------------------------------------------------------------------------------- // Returns a rotation matrix for a rotation around an arbitrary axis. template <typename TReal> -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; +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> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) -{ +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; @@ -653,8 +644,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<T // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) -{ +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; @@ -673,9 +664,9 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal */ // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, - const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) -{ +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); diff --git a/thirdparty/assimp/include/assimp/mesh.h b/thirdparty/assimp/include/assimp/mesh.h index f1628f1f54..fbf2a857ad 100644 --- a/thirdparty/assimp/include/assimp/mesh.h +++ b/thirdparty/assimp/include/assimp/mesh.h @@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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> @@ -248,6 +252,9 @@ struct aiVertexWeight { }; +// Forward declare aiNode (pointer use only) +struct aiNode; + // --------------------------------------------------------------------------- /** @brief A single bone of a mesh. * @@ -264,6 +271,16 @@ struct aiBone { //! 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; @@ -418,11 +435,11 @@ struct aiAnimMesh /**Anim Mesh name */ C_STRUCT aiString mName; - /** Replacement for aiMesh::mVertices. If this array is non-NULL, + /** 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-NULL as well - animation + * 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 NULL and the corresponding source + * a replacement array is nullptr and the corresponding source * array is not, the source data is taken instead)*/ C_STRUCT aiVector3D* mVertices; @@ -596,7 +613,7 @@ struct aiMesh C_STRUCT aiVector3D* mVertices; /** Vertex normals. - * The array contains normalized vectors, NULL if not present. + * 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 @@ -619,7 +636,7 @@ struct aiMesh /** Vertex tangents. * The tangent of a vertex points in the direction of the positive - * X texture axis. The array contains normalized vectors, NULL if + * 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 @@ -633,7 +650,7 @@ struct aiMesh /** Vertex bitangents. * The bitangent of a vertex points in the direction of the positive - * Y texture axis. The array contains normalized vectors, NULL if not + * 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. @@ -642,14 +659,14 @@ struct aiMesh /** Vertex color sets. * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex - * colors per vertex. NULL if not present. Each array is + * 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. NULL if not present. The array is mNumVertices in size. + * vertex. nullptr if not present. The array is mNumVertices in size. */ C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; @@ -671,7 +688,7 @@ struct aiMesh C_STRUCT aiFace* mFaces; /** The number of bones this mesh contains. - * Can be 0, in which case the mBones array is NULL. + * Can be 0, in which case the mBones array is nullptr. */ unsigned int mNumBones; @@ -769,7 +786,10 @@ struct aiMesh // DO NOT REMOVE THIS ADDITIONAL CHECK if (mNumBones && mBones) { for( unsigned int a = 0; a < mNumBones; a++) { - delete mBones[a]; + if(mBones[a]) + { + delete mBones[a]; + } } delete [] mBones; } diff --git a/thirdparty/assimp/include/assimp/metadata.h b/thirdparty/assimp/include/assimp/metadata.h index 3a1dd1442a..849d90f485 100644 --- a/thirdparty/assimp/include/assimp/metadata.h +++ b/thirdparty/assimp/include/assimp/metadata.h @@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 diff --git a/thirdparty/assimp/include/assimp/pbrmaterial.h b/thirdparty/assimp/include/assimp/pbrmaterial.h index ce5f822173..892a6347f7 100644 --- a/thirdparty/assimp/include/assimp/pbrmaterial.h +++ b/thirdparty/assimp/include/assimp/pbrmaterial.h @@ -5,8 +5,6 @@ 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, @@ -44,9 +42,14 @@ 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 diff --git a/thirdparty/assimp/include/assimp/postprocess.h b/thirdparty/assimp/include/assimp/postprocess.h index 2a74414216..4b6732e80a 100644 --- a/thirdparty/assimp/include/assimp/postprocess.h +++ b/thirdparty/assimp/include/assimp/postprocess.h @@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_POSTPROCESS_H_INC #define AI_POSTPROCESS_H_INC -#include "types.h" +#include <assimp/types.h> + +#ifdef __GNUC__ +# pragma GCC system_header +#endif #ifdef __cplusplus extern "C" { @@ -316,6 +320,19 @@ enum aiPostProcessSteps */ 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. @@ -533,6 +550,8 @@ enum aiPostProcessSteps */ aiProcess_Debone = 0x4000000, + + // ------------------------------------------------------------------------- /** <hr>This step will perform a global scale of the model. * diff --git a/thirdparty/assimp/include/assimp/qnan.h b/thirdparty/assimp/include/assimp/qnan.h index 0918bde5e7..06780da5b8 100644 --- a/thirdparty/assimp/include/assimp/qnan.h +++ b/thirdparty/assimp/include/assimp/qnan.h @@ -50,19 +50,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 -{ +union _IEEESingle { float Float; struct { @@ -75,8 +79,7 @@ union _IEEESingle // --------------------------------------------------------------------------- /** Data structure to represent the bit pattern of a 64 Bit * IEEE 754 floating-point number. */ -union _IEEEDouble -{ +union _IEEEDouble { double Double; struct { @@ -89,8 +92,7 @@ union _IEEEDouble // --------------------------------------------------------------------------- /** Check whether a given float is qNaN. * @param in Input value */ -AI_FORCE_INLINE bool is_qnan(float in) -{ +AI_FORCE_INLINE bool is_qnan(float in) { // the straightforward solution does not work: // return (in != in); // compiler generates code like this @@ -107,8 +109,7 @@ AI_FORCE_INLINE bool is_qnan(float in) // --------------------------------------------------------------------------- /** Check whether a given double is qNaN. * @param in Input value */ -AI_FORCE_INLINE bool is_qnan(double in) -{ +AI_FORCE_INLINE bool is_qnan(double in) { // the straightforward solution does not work: // return (in != in); // compiler generates code like this @@ -127,8 +128,7 @@ AI_FORCE_INLINE bool is_qnan(double in) * * Denorms return false, they're treated like normal values. * @param in Input value */ -AI_FORCE_INLINE bool is_special_float(float in) -{ +AI_FORCE_INLINE bool is_special_float(float in) { _IEEESingle temp; memcpy(&temp, &in, sizeof(float)); return (temp.IEEE.Exp == (1u << 8)-1); @@ -139,8 +139,7 @@ AI_FORCE_INLINE bool is_special_float(float in) * * Denorms return false, they're treated like normal values. * @param in Input value */ -AI_FORCE_INLINE bool is_special_float(double in) -{ +AI_FORCE_INLINE bool is_special_float(double in) { _IEEESingle temp; memcpy(&temp, &in, sizeof(float)); return (temp.IEEE.Exp == (1u << 11)-1); @@ -150,15 +149,13 @@ AI_FORCE_INLINE bool is_special_float(double in) /** Check whether a float is NOT qNaN. * @param in Input value */ template<class TReal> -AI_FORCE_INLINE bool is_not_qnan(TReal in) -{ +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() -{ +AI_FORCE_INLINE ai_real get_qnan() { return std::numeric_limits<ai_real>::quiet_NaN(); } diff --git a/thirdparty/assimp/include/assimp/quaternion.h b/thirdparty/assimp/include/assimp/quaternion.h index 96574d24b9..ae45959b41 100644 --- a/thirdparty/assimp/include/assimp/quaternion.h +++ b/thirdparty/assimp/include/assimp/quaternion.h @@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef __cplusplus -#include "defs.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/defs.h> template <typename TReal> class aiVector3t; template <typename TReal> class aiMatrix3x3t; diff --git a/thirdparty/assimp/include/assimp/quaternion.inl b/thirdparty/assimp/include/assimp/quaternion.inl index c26648215e..3ce514d1bb 100644 --- a/thirdparty/assimp/include/assimp/quaternion.inl +++ b/thirdparty/assimp/include/assimp/quaternion.inl @@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_QUATERNION_INL_INC #define AI_QUATERNION_INL_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #ifdef __cplusplus -#include "quaternion.h" +#include <assimp/quaternion.h> #include <cmath> diff --git a/thirdparty/assimp/include/assimp/scene.h b/thirdparty/assimp/include/assimp/scene.h index 2667db85b3..b76709eb15 100644 --- a/thirdparty/assimp/include/assimp/scene.h +++ b/thirdparty/assimp/include/assimp/scene.h @@ -48,14 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_SCENE_H_INC #define AI_SCENE_H_INC -#include "types.h" -#include "texture.h" -#include "mesh.h" -#include "light.h" -#include "camera.h" -#include "material.h" -#include "anim.h" -#include "metadata.h" +#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> @@ -106,13 +110,13 @@ struct ASSIMP_API aiNode /** The transformation relative to the node's parent. */ C_STRUCT aiMatrix4x4 mTransformation; - /** Parent node. NULL if this node is the root node. */ + /** 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. NULL if mNumChildren is 0. */ + /** The child nodes of this node. nullptr if mNumChildren is 0. */ C_STRUCT aiNode** mChildren; /** The number of meshes of this node. */ @@ -123,7 +127,7 @@ struct ASSIMP_API aiNode */ unsigned int* mMeshes; - /** Metadata associated with this node or NULL if there is no metadata. + /** 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. @@ -145,7 +149,7 @@ struct ASSIMP_API aiNode * of the scene. * * @param name Name to search for - * @return NULL or a valid Node if the search was successful. + * @return nullptr or a valid Node if the search was successful. */ inline const aiNode* FindNode(const aiString& name) const { @@ -340,7 +344,7 @@ struct aiScene #ifdef __cplusplus - //! Default constructor - set everything to 0/NULL + //! Default constructor - set everything to 0/nullptr ASSIMP_API aiScene(); //! Destructor @@ -349,33 +353,33 @@ struct 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 != NULL && mNumMeshes > 0; + 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 != NULL && mNumMaterials > 0; + return mMaterials != nullptr && mNumMaterials > 0; } //! Check whether the scene contains lights inline bool HasLights() const { - return mLights != NULL && mNumLights > 0; + return mLights != nullptr && mNumLights > 0; } //! Check whether the scene contains textures inline bool HasTextures() const { - return mTextures != NULL && mNumTextures > 0; + return mTextures != nullptr && mNumTextures > 0; } //! Check whether the scene contains cameras inline bool HasCameras() const { - return mCameras != NULL && mNumCameras > 0; + return mCameras != nullptr && mNumCameras > 0; } //! Check whether the scene contains animations inline bool HasAnimations() const { - return mAnimations != NULL && mNumAnimations > 0; + return mAnimations != nullptr && mNumAnimations > 0; } //! Returns a short filename from a full path diff --git a/thirdparty/assimp/include/assimp/texture.h b/thirdparty/assimp/include/assimp/texture.h index dc6cbef65c..0867659f46 100644 --- a/thirdparty/assimp/include/assimp/texture.h +++ b/thirdparty/assimp/include/assimp/texture.h @@ -5,8 +5,6 @@ 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, @@ -53,13 +51,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_TEXTURE_H_INC #define AI_TEXTURE_H_INC -#include "types.h" +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include <assimp/types.h> #ifdef __cplusplus extern "C" { #endif - // -------------------------------------------------------------------------------- /** \def AI_EMBEDDED_TEXNAME_PREFIX @@ -79,7 +80,6 @@ extern "C" { # define AI_MAKE_EMBEDDED_TEXNAME(_n_) AI_EMBEDDED_TEXNAME_PREFIX # _n_ #endif - #include "./Compiler/pushpack1.h" // -------------------------------------------------------------------------------- @@ -87,8 +87,7 @@ extern "C" { * * Used by aiTexture. */ -struct aiTexel -{ +struct aiTexel { unsigned char b,g,r,a; #ifdef __cplusplus diff --git a/thirdparty/assimp/include/assimp/types.h b/thirdparty/assimp/include/assimp/types.h index 331b8cd03f..e32cae331c 100644 --- a/thirdparty/assimp/include/assimp/types.h +++ b/thirdparty/assimp/include/assimp/types.h @@ -48,22 +48,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 "defs.h" +#include <assimp/defs.h> // Some types moved to separate header due to size of operators -#include "vector3.h" -#include "vector2.h" -#include "color4.h" -#include "matrix3x3.h" -#include "matrix4x4.h" -#include "quaternion.h" +#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> @@ -71,7 +79,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <string> // for aiString::Set(const std::string&) namespace Assimp { - //! @cond never +//! @cond never namespace Intern { // -------------------------------------------------------------------- /** @brief Internal helper class to utilize our internal new/delete @@ -269,8 +277,8 @@ struct aiString } /** Copy constructor */ - aiString(const aiString& rOther) : - length(rOther.length) + aiString(const aiString& rOther) + : length(rOther.length) { // Crop the string to the maximum length length = length>=MAXLEN?MAXLEN-1:length; @@ -280,7 +288,7 @@ struct aiString /** Constructor from std::string */ explicit aiString(const std::string& pString) : - length(pString.length()) + length( (ai_uint32) pString.length()) { length = length>=MAXLEN?MAXLEN-1:length; memcpy( data, pString.c_str(), length); @@ -292,15 +300,15 @@ struct aiString if( pString.length() > MAXLEN - 1) { return; } - length = pString.length(); + 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 size_t len = ::strlen(sz); - if( len > MAXLEN - 1) { + const ai_int32 len = (ai_uint32) ::strlen(sz); + if( len > (ai_int32)MAXLEN - 1) { return; } length = len; @@ -346,7 +354,7 @@ struct aiString /** Append a string to the string */ void Append (const char* app) { - const size_t len = ::strlen(app); + const ai_uint32 len = (ai_uint32) ::strlen(app); if (!len) { return; } @@ -379,7 +387,7 @@ struct aiString /** 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.*/ - size_t length; + ai_uint32 length; /** String buffer. Size limit is MAXLEN */ char data[MAXLEN]; diff --git a/thirdparty/assimp/include/assimp/vector2.h b/thirdparty/assimp/include/assimp/vector2.h index d5ef001542..c8b1ebbbc2 100644 --- a/thirdparty/assimp/include/assimp/vector2.h +++ b/thirdparty/assimp/include/assimp/vector2.h @@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_VECTOR2D_H_INC #define AI_VECTOR2D_H_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #ifdef __cplusplus # include <cmath> #else diff --git a/thirdparty/assimp/include/assimp/vector2.inl b/thirdparty/assimp/include/assimp/vector2.inl index 3b7a7beabb..4bbf432ff8 100644 --- a/thirdparty/assimp/include/assimp/vector2.inl +++ b/thirdparty/assimp/include/assimp/vector2.inl @@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_VECTOR2D_INL_INC #define AI_VECTOR2D_INL_INC +#ifdef __GNUC__ +# pragma GCC system_header +#endif + #ifdef __cplusplus -#include "vector2.h" +#include <assimp/vector2.h> #include <cmath> diff --git a/thirdparty/assimp/include/assimp/vector3.h b/thirdparty/assimp/include/assimp/vector3.h index 7ff25cf0ad..fffeb12ad7 100644 --- a/thirdparty/assimp/include/assimp/vector3.h +++ b/thirdparty/assimp/include/assimp/vector3.h @@ -47,13 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 "defs.h" +#include <assimp/defs.h> #ifdef __cplusplus @@ -63,16 +67,13 @@ template<typename TReal> class aiMatrix4x4t; // --------------------------------------------------------------------------- /** Represents a three-dimensional vector. */ template <typename TReal> -class aiVector3t -{ +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; -public: - // combined operators const aiVector3t& operator += (const aiVector3t& o); const aiVector3t& operator -= (const aiVector3t& o); @@ -97,7 +98,6 @@ public: template <typename TOther> operator aiVector3t<TOther> () const; -public: /** @brief Set the components of a vector * @param pX X component * @param pY Y component diff --git a/thirdparty/assimp/include/assimp/vector3.inl b/thirdparty/assimp/include/assimp/vector3.inl index 2fce6eddee..6682d3b32c 100644 --- a/thirdparty/assimp/include/assimp/vector3.inl +++ b/thirdparty/assimp/include/assimp/vector3.inl @@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_VECTOR3D_INL_INC #ifdef __cplusplus -#include "vector3.h" +#include <assimp/vector3.h> #include <cmath> diff --git a/thirdparty/assimp/include/assimp/version.h b/thirdparty/assimp/include/assimp/version.h index c62a40e118..2fdd37a43c 100644 --- a/thirdparty/assimp/include/assimp/version.h +++ b/thirdparty/assimp/include/assimp/version.h @@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_VERSION_H_INC #define AI_VERSION_H_INC -#include "defs.h" +#include <assimp/defs.h> #ifdef __cplusplus extern "C" { |