Preliminary Blender FBX support

limitations:
- always has to use generated normal's.
- some animations won't be compatible (yet)

Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
This commit is contained in:
Gordon MacPherson 2021-01-03 20:16:57 +00:00
parent 3032b38b52
commit 31bc1af82a
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,
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, HashMap<int, Vector2> > uvs_0_raw = extract_per_vertex_data(
vertices.size(),
@ -370,6 +350,9 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
normals_ptr[vertex]);
}
if (state.is_blender_fbx) {
morph_st->generate_normals();
}
morph_st->generate_tangents();
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)) {
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.
if (uvs_0_raw.size() > 0) {
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.");
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);
}

View file

@ -64,6 +64,7 @@ struct FBXSkeleton;
struct ImportState {
bool enable_material_import = true;
bool enable_animation_import = true;
bool is_blender_fbx = false;
Map<StringName, Ref<Texture> > cached_image_searches;
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) {
Spatial *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8);
// 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 {
ERR_PRINT("We can't import Blender FBX files for the time being. Please favor glTF 2.0 when exporting from Blender.");
if (is_blender_fbx) {
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.");
}
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 {
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 uint32_t p_flags,
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;
state.is_blender_fbx = p_is_blender_fbx;
state.path = p_path;
state.animation_player = NULL;

View file

@ -115,7 +115,9 @@ private:
Spatial *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document,
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>
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);