1 /*************************************************************************/ 2 /* editor_scene_importer_assimp.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 31 #ifndef EDITOR_SCENE_IMPORTER_ASSIMP_H 32 #define EDITOR_SCENE_IMPORTER_ASSIMP_H 33 34 #ifdef TOOLS_ENABLED 35 #include "core/bind/core_bind.h" 36 #include "core/io/resource_importer.h" 37 #include "core/vector.h" 38 #include "editor/import/resource_importer_scene.h" 39 #include "editor/project_settings_editor.h" 40 #include "scene/3d/mesh_instance.h" 41 #include "scene/3d/skeleton.h" 42 #include "scene/3d/spatial.h" 43 #include "scene/animation/animation_player.h" 44 #include "scene/resources/animation.h" 45 #include "scene/resources/surface_tool.h" 46 47 #include <assimp/matrix4x4.h> 48 #include <assimp/scene.h> 49 #include <assimp/types.h> 50 #include <assimp/DefaultLogger.hpp> 51 #include <assimp/LogStream.hpp> 52 #include <assimp/Logger.hpp> 53 #include <map> 54 55 #include "import_state.h" 56 #include "import_utils.h" 57 58 using namespace AssimpImporter; 59 60 class AssimpStream : public Assimp::LogStream { 61 public: 62 // Constructor AssimpStream()63 AssimpStream() {} 64 65 // Destructor ~AssimpStream()66 ~AssimpStream() {} 67 // Write something using your own functionality write(const char * message)68 void write(const char *message) { 69 print_verbose(String("Open Asset Import: ") + String(message).strip_edges()); 70 } 71 }; 72 73 class EditorSceneImporterAssimp : public EditorSceneImporter { 74 private: 75 GDCLASS(EditorSceneImporterAssimp, EditorSceneImporter); 76 77 struct AssetImportAnimation { 78 enum Interpolation { 79 INTERP_LINEAR, 80 INTERP_STEP, 81 INTERP_CATMULLROMSPLINE, 82 INTERP_CUBIC_SPLINE 83 }; 84 }; 85 86 struct BoneInfo { 87 uint32_t bone; 88 float weight; 89 }; 90 91 Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, 92 const aiNode *assimp_node, Ref<Skin> &skin, 93 Skeleton *&skeleton_assigned); 94 95 // simple object creation functions 96 Spatial *create_light(ImportState &state, 97 const String &node_name, 98 Transform &look_at_transform); 99 Spatial *create_camera( 100 ImportState &state, 101 const String &node_name, 102 Transform &look_at_transform); 103 // non recursive - linear so must not use recursive arguments 104 MeshInstance *create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform); 105 // recursive node generator 106 void _generate_node(ImportState &state, const aiNode *assimp_node); 107 void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id, 108 int anim_fps, Ref<Animation> animation, float ticks_per_second, 109 Skeleton *skeleton, const NodePath &node_path, 110 const String &node_name, aiBone *track_bone); 111 112 void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps); 113 Node *get_node_by_name(ImportState &state, String name); 114 aiBone *get_bone_from_stack(ImportState &state, aiString name); 115 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); 116 117 template <class T> 118 T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp); 119 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; 120 121 struct ImportFormat { 122 Vector<String> extensions; 123 bool is_default; 124 }; 125 126 protected: 127 static void _bind_methods(); 128 129 public: EditorSceneImporterAssimp()130 EditorSceneImporterAssimp() { 131 Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE); 132 unsigned int severity = Assimp::Logger::Info | Assimp::Logger::Err | Assimp::Logger::Warn; 133 Assimp::DefaultLogger::get()->attachStream(new AssimpStream(), severity); 134 } ~EditorSceneImporterAssimp()135 ~EditorSceneImporterAssimp() { 136 Assimp::DefaultLogger::kill(); 137 } 138 139 virtual void get_extensions(List<String> *r_extensions) const; 140 virtual uint32_t get_import_flags() const; 141 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); 142 Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path); 143 144 static void RegenerateBoneStack(ImportState &state); 145 146 void RegenerateBoneStack(ImportState &state, aiMesh *mesh); 147 }; 148 #endif 149 #endif 150