Merge pull request #44900 from RevoluPowered/fbx-add-blender-support

Preliminary Blender FBX support [4.0]
This commit is contained in:
Rémi Verschelde 2021-01-06 09:43:08 +01:00 committed by GitHub
commit c197a565f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 25 deletions

View File

@ -135,26 +135,6 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
&collect_all, &collect_all,
HashMap<int, Vector3>()); HashMap<int, Vector3>());
// List<int> keys;
// normals.get_key_list(&keys);
//
// const std::vector<Assimp::FBX::MeshGeometry::Edge>& edges = mesh_geometry->get_edge_map();
// for (int index = 0; index < keys.size(); index++) {
// const int key = keys[index];
// const int v1 = edges[key].vertex_0;
// const int v2 = edges[key].vertex_1;
// const Vector3& n1 = normals.get(v1);
// const Vector3& n2 = normals.get(v2);
// print_verbose("[" + itos(v1) + "] n1: " + n1 + "\n[" + itos(v2) + "] n2: " + n2);
// //print_verbose("[" + itos(key) + "] n1: " + n1 + ", n2: " + n2) ;
// //print_verbose("vindex: " + itos(edges[key].vertex_0) + ", vindex2: " + itos(edges[key].vertex_1));
// //Vector3 ver1 = vertices[edges[key].vertex_0];
// //Vector3 ver2 = vertices[edges[key].vertex_1];
// /*real_t angle1 = Math::rad2deg(n1.angle_to(n2));
// real_t angle2 = Math::rad2deg(n2.angle_to(n1));
// print_verbose("angle of normals: " + rtos(angle1) + " angle 2" + rtos(angle2));*/
// }
HashMap<int, Vector2> uvs_0; HashMap<int, Vector2> uvs_0;
HashMap<int, HashMap<int, Vector2>> uvs_0_raw = extract_per_vertex_data( HashMap<int, HashMap<int, Vector2>> uvs_0_raw = extract_per_vertex_data(
vertices.size(), vertices.size(),
@ -371,6 +351,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
normals_ptr[vertex]); normals_ptr[vertex]);
} }
if (state.is_blender_fbx) {
morph_st->generate_normals();
}
morph_st->generate_tangents(); morph_st->generate_tangents();
surface->morphs.push_back(morph_st->commit_to_arrays()); surface->morphs.push_back(morph_st->commit_to_arrays());
} }
@ -393,6 +376,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) { for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) {
SurfaceData *surface = surfaces.getptr(*surface_id); SurfaceData *surface = surfaces.getptr(*surface_id);
if (state.is_blender_fbx) {
surface->surface_tool->generate_normals();
}
// you can't generate them without a valid uv map. // you can't generate them without a valid uv map.
if (uvs_0_raw.size() > 0) { if (uvs_0_raw.size() > 0) {
surface->surface_tool->generate_tangents(); surface->surface_tool->generate_tangents();
@ -785,7 +771,7 @@ void FBXMeshData::add_vertex(
const Vector3 &p_morph_normal) { const Vector3 &p_morph_normal) {
ERR_FAIL_INDEX_MSG(p_vertex, (Vertex)p_vertices_position.size(), "FBX file is corrupted, the position of the vertex can't be retrieved."); ERR_FAIL_INDEX_MSG(p_vertex, (Vertex)p_vertices_position.size(), "FBX file is corrupted, the position of the vertex can't be retrieved.");
if (p_normals.has(p_vertex)) { if (p_normals.has(p_vertex) && !state.is_blender_fbx) {
p_surface_tool->set_normal(p_normals[p_vertex] + p_morph_normal); p_surface_tool->set_normal(p_normals[p_vertex] + p_morph_normal);
} }

View File

@ -64,6 +64,7 @@ struct FBXSkeleton;
struct ImportState { struct ImportState {
bool enable_material_import = true; bool enable_material_import = true;
bool enable_animation_import = true; bool enable_animation_import = true;
bool is_blender_fbx = false;
Map<StringName, Ref<Texture>> cached_image_searches; Map<StringName, Ref<Texture>> cached_image_searches;
Map<uint64_t, Ref<Material>> cached_materials; Map<uint64_t, Ref<Material>> cached_materials;

View File

@ -180,10 +180,12 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl
} }
if (is_blender_fbx) { if (is_blender_fbx) {
WARN_PRINT("Blender FBX files will not work properly with keyframes or skeletons until we make fixes. Please stand by."); WARN_PRINT("We don't officially support Blender FBX animations yet, due to issues with upstream Blender,\n"
"so please wait for us to work around remaining issues. We will continue to import the file but it may be broken.\n"
"For minimal breakage, please export FBX from Blender with -Z forward, and Y up.");
} }
Node3D *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8); Node3D *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8, is_blender_fbx);
// todo: move to document shutdown (will need to be validated after moving; this code has been validated already) // todo: move to document shutdown (will need to be validated after moving; this code has been validated already)
for (FBXDocParser::TokenPtr token : tokens) { for (FBXDocParser::TokenPtr token : tokens) {
if (token) { if (token) {
@ -327,8 +329,10 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
const FBXDocParser::Document *p_document, const FBXDocParser::Document *p_document,
const uint32_t p_flags, const uint32_t p_flags,
int p_bake_fps, int p_bake_fps,
const int32_t p_max_bone_weights) { const int32_t p_max_bone_weights,
bool p_is_blender_fbx) {
ImportState state; ImportState state;
state.is_blender_fbx = p_is_blender_fbx;
state.path = p_path; state.path = p_path;
state.animation_player = NULL; state.animation_player = NULL;

View File

@ -114,7 +114,9 @@ private:
Node3D *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document, Node3D *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document,
const uint32_t p_flags, const uint32_t p_flags,
int p_bake_fps, const int32_t p_max_bone_weights); int p_bake_fps,
const int32_t p_max_bone_weights,
bool p_is_blender_fbx);
template <class T> template <class T>
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp); T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);