fix: compute face normals when OBJ has no vn lines

- ObjLoader.ParseFace: if no normals in OBJ, compute face normal from
  first triangle using MeshMath.ComputeFaceNormal and apply to all face vertices
- cube.obj has no vn lines, so all faces previously had normal (0,1,0)
- Now each face has correct outward-facing normal for proper lighting
This commit is contained in:
emil28092005
2026-06-18 12:42:13 +03:00
parent d6ca80c678
commit e740cf1214
+17 -2
View File
@@ -3,7 +3,6 @@ using Engine.Core;
using Engine.Core.Components; using Engine.Core.Components;
namespace Engine.Graphics.Loaders; namespace Engine.Graphics.Loaders;
/// <summary> /// <summary>
/// Minimal OBJ loader. /// Minimal OBJ loader.
/// </summary> /// </summary>
@@ -66,6 +65,8 @@ public static class ObjLoader
var faceIndices = new List<uint>(); var faceIndices = new List<uint>();
faceNormals.Clear(); faceNormals.Clear();
var hasNormals = false;
for (int i = 1; i < parts.Length; i++) for (int i = 1; i < parts.Length; i++)
{ {
var sub = parts[i].Split('/'); var sub = parts[i].Split('/');
@@ -76,13 +77,27 @@ public static class ObjLoader
if (sub.Length > 2 && !string.IsNullOrEmpty(sub[2])) if (sub.Length > 2 && !string.IsNullOrEmpty(sub[2]))
{ {
normal = normals[int.Parse(sub[2]) - 1]; normal = normals[int.Parse(sub[2]) - 1];
hasNormals = true;
} }
vertices.Add(new Vertex(pos, color, normal)); vertices.Add(new Vertex(pos, color, normal));
faceIndices.Add((uint)(vertices.Count - 1)); faceIndices.Add((uint)(vertices.Count - 1));
} }
// Triangulate as a fan. if (!hasNormals && faceIndices.Count >= 3)
{
var a = vertices[(int)faceIndices[0]].Position;
var b = vertices[(int)faceIndices[1]].Position;
var c = vertices[(int)faceIndices[2]].Position;
var faceNormal = MeshMath.ComputeFaceNormal(a, b, c);
for (int i = 0; i < faceIndices.Count; i++)
{
var v = vertices[(int)faceIndices[i]];
v.Normal = faceNormal;
vertices[(int)faceIndices[i]] = v;
}
}
for (int i = 2; i < faceIndices.Count; i++) for (int i = 2; i < faceIndices.Count; i++)
{ {
indices.Add(faceIndices[0]); indices.Add(faceIndices[0]);