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

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

View file

@ -134,26 +134,6 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
&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(),
@ -370,6 +350,9 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
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());
} }
@ -392,6 +375,9 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
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();
@ -790,7 +776,7 @@ void FBXMeshData::add_vertex(
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->add_normal(p_normals[p_vertex] + p_morph_normal); p_surface_tool->add_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<SpatialMaterial> > cached_materials; Map<uint64_t, Ref<SpatialMaterial> > cached_materials;

View file

@ -180,21 +180,23 @@ Node *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_flag
} }
} }
if (!is_blender_fbx) { if (is_blender_fbx) {
Spatial *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8); WARN_PRINT("We don't officially support Blender FBX animations yet, due to issues with upstream Blender,\n"
// todo: move to document shutdown (will need to be validated after moving; this code has been validated already) "so please wait for us to work around remaining issues. We will continue to import the file but it may be broken.\n"
for (FBXDocParser::TokenPtr token : tokens) { "For minimal breakage, please export FBX from Blender with -Z forward, and Y up.");
if (token) {
delete token;
token = nullptr;
}
}
return spatial;
} else {
ERR_PRINT("We can't import Blender FBX files for the time being. Please favor glTF 2.0 when exporting from Blender.");
} }
Spatial *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)
for (FBXDocParser::TokenPtr token : tokens) {
if (token) {
delete token;
token = nullptr;
}
}
return spatial;
} else { } else {
ERR_PRINT(vformat("Cannot import FBX file: %s. It uses file format %d which is unsupported by Godot. Please re-export it or convert it to a newer format.", p_path, doc.FBXVersion())); ERR_PRINT(vformat("Cannot import FBX file: %s. It uses file format %d which is unsupported by Godot. Please re-export it or convert it to a newer format.", p_path, doc.FBXVersion()));
} }
@ -368,9 +370,11 @@ Spatial *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

@ -115,7 +115,9 @@ private:
Spatial *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document, Spatial *_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);