Skip to content

Commit

Permalink
Preliminary Blender FBX support
Browse files Browse the repository at this point in the history
limitations:
- always has to use generated normal's.
- some animations won't be compatible (yet)

Co-authored-by: Rémi Verschelde <[email protected]>
  • Loading branch information
RevoluPowered and akien-mga committed Jan 5, 2021
1 parent 3032b38 commit 31bc1af
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 35 deletions.
28 changes: 7 additions & 21 deletions modules/fbx/data/fbx_mesh_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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());
}
Expand All @@ -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();
Expand Down Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions modules/fbx/data/import_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 17 additions & 13 deletions modules/fbx/editor_scene_importer_fbx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
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.");
}

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 {
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()));
}
Expand Down Expand Up @@ -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;

Expand Down
4 changes: 3 additions & 1 deletion modules/fbx/editor_scene_importer_fbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ class EditorSceneImporterFBX : public EditorSceneImporter {

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);
Expand Down

0 comments on commit 31bc1af

Please sign in to comment.