@@ -611,9 +611,50 @@ Error FBXDocument::_parse_meshes(Ref<FBXState> p_state) {
611611 array[Mesh::ARRAY_VERTEX ] = _decode_vertex_attrib_vec3 (fbx_mesh->vertex_position , indices);
612612 }
613613
614- // Normals always exist as they're generated if missing,
615- // see `ufbx_load_opts.generate_missing_normals`.
616- Vector<Vector3> normals = _decode_vertex_attrib_vec3 (fbx_mesh->vertex_normal , indices);
614+ // Generate normals respecting FBX smoothing groups
615+ Vector<Vector3> normals;
616+ normals.resize (vertex_num);
617+
618+ HashMap<Vector3, Vector3> normal_accum_smooth;
619+ HashMap<Vector3, int > normal_count_smooth;
620+ HashMap<Vector3, Vector3> normal_accum_faceted;
621+ HashMap<Vector3, int > normal_count_faceted;
622+
623+ for (size_t face_idx = 0 ; face_idx < fbx_mesh->faces .count ; face_idx++) {
624+ ufbx_face face = fbx_mesh->faces .data [face_idx];
625+
626+ if (face.num_indices >= 3 ) {
627+ Vector3 v0 = _as_vec3 (fbx_mesh->vertex_position [face.index_begin ]);
628+ Vector3 v1 = _as_vec3 (fbx_mesh->vertex_position [face.index_begin + 1 ]);
629+ Vector3 v2 = _as_vec3 (fbx_mesh->vertex_position [face.index_begin + 2 ]);
630+
631+ Vector3 face_normal = Plane (v0, v1, v2).normal ;
632+
633+ bool is_smooth = (face_idx < fbx_mesh->face_smoothing .count ) ? fbx_mesh->face_smoothing .data [face_idx] : false ;
634+
635+ HashMap<Vector3, Vector3> &normal_accum = is_smooth ? normal_accum_smooth : normal_accum_faceted;
636+ HashMap<Vector3, int > &normal_count = is_smooth ? normal_count_smooth : normal_count_faceted;
637+
638+ normal_accum[v0] += face_normal;
639+ normal_accum[v1] += face_normal;
640+ normal_accum[v2] += face_normal;
641+ normal_count[v0]++;
642+ normal_count[v1]++;
643+ normal_count[v2]++;
644+ }
645+ }
646+
647+ for (int i = 0 ; i < vertex_num; i++) {
648+ Vector3 vertex_pos = _as_vec3 (fbx_mesh->vertex_position [indices[i]]);
649+
650+ if (normal_count_smooth.has (vertex_pos) && normal_count_smooth[vertex_pos] > 0 ) {
651+ normals.write [i] = (normal_accum_smooth[vertex_pos] / normal_count_smooth[vertex_pos]).normalized ();
652+ } else if (normal_count_faceted.has (vertex_pos) && normal_count_faceted[vertex_pos] > 0 ) {
653+ normals.write [i] = (normal_accum_faceted[vertex_pos] / normal_count_faceted[vertex_pos]).normalized ();
654+ } else {
655+ normals.write [i] = Vector3 (0 , 1 , 0 );
656+ }
657+ }
617658 array[Mesh::ARRAY_NORMAL ] = normals;
618659
619660 if (fbx_mesh->vertex_tangent .exists ) {
@@ -2053,7 +2094,7 @@ Error FBXDocument::_parse(Ref<FBXState> p_state, const String &p_path, Ref<FileA
20532094 opts.ignore_geometry = true ;
20542095 opts.ignore_embedded = true ;
20552096 }
2056- opts.generate_missing_normals = true ;
2097+ opts.generate_missing_normals = false ;
20572098
20582099 ThreadPoolFBX thread_pool;
20592100 thread_pool.pool = WorkerThreadPool::get_singleton ();
0 commit comments