Preliminary Blender FBX support [4.0]

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:29:38 +00:00
parent cdfcf68af9
commit 74a72cf85e
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,
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(),
@ -371,6 +351,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
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());
}
@ -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)) {
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();
@ -785,7 +771,7 @@ void FBXMeshData::add_vertex(
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.");
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);
}

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<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) {
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)
for (FBXDocParser::TokenPtr token : tokens) {
if (token) {
@ -327,8 +329,10 @@ Node3D *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

@ -114,7 +114,9 @@ private:
Node3D *_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);