Properly create and apply color based model materials

This commit is contained in:
Jarrod Doyle 2024-08-18 12:37:03 +01:00
parent 20cf0f7292
commit 6db4d75a37
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
1 changed files with 37 additions and 31 deletions

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Godot; using Godot;
using Godot.Collections;
using KeepersCompound.LGS; using KeepersCompound.LGS;
using KeepersCompound.TMV.UI; using KeepersCompound.TMV.UI;
@ -37,25 +35,34 @@ public partial class Model : Node3D
MatchCasing = MatchCasing.CaseInsensitive, MatchCasing = MatchCasing.CaseInsensitive,
RecurseSubdirectories = true, RecurseSubdirectories = true,
}; };
var textures = new List<ImageTexture>(); var materials = new List<StandardMaterial3D>();
foreach (var material in modelFile.Materials) foreach (var material in modelFile.Materials)
{
if (material.Type == 0)
{ {
var paths = Directory.GetFiles(baseDir, material.Name, options); var paths = Directory.GetFiles(baseDir, material.Name, options);
if (paths.IsEmpty()) continue; if (paths.IsEmpty()) continue;
var texture = TextureLoader.LoadTexture(paths[0]); materials.Add(new StandardMaterial3D
var saveName = material.Name.GetBaseName() + ".png"; {
texture.GetImage().SavePng(ProjectSettings.GlobalizePath($"user://debug/{saveName}")); AlbedoTexture = TextureLoader.LoadTexture(paths[0])
textures.Add(texture); });
}
else
{
var b = (material.Handle) & 0xff;
var g = (material.Handle >> 8) & 0xff;
var r = (material.Handle >> 16) & 0xff;
GD.Print($"Handle: {material.Handle}, R: {r}, G: {g}, B: {b}");
var colour = new Color(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
materials.Add(new StandardMaterial3D
{
AlbedoColor = colour
});
}
} }
var mat = new StandardMaterial3D var mesh = new ArrayMesh();
{
AlbedoTexture = textures[0]
};
// TODO: Support multiple materials and colour based materials
var surfaceData = new MeshSurfaceData();
foreach (var poly in modelFile.Polygons) foreach (var poly in modelFile.Polygons)
{ {
var vertices = new List<Vector3>(); var vertices = new List<Vector3>();
@ -72,26 +79,25 @@ public partial class Model : Node3D
} }
else else
{ {
var uv = (i % 4) switch uvs.Add(Vector2.Zero);
{ }
0 => new Vector2(0, 0),
1 => new Vector2(0, 1),
2 => new Vector2(1, 0),
3 => new Vector2(1, 1),
_ => throw new NotImplementedException(),
};
uvs.Add(uv);
}
} }
var surfaceData = new MeshSurfaceData();
surfaceData.AddPolygon(vertices, normal, uvs, uvs); surfaceData.AddPolygon(vertices, normal, uvs, uvs);
}
var array = surfaceData.BuildSurfaceArray(); var array = surfaceData.BuildSurfaceArray();
var mesh = new ArrayMesh();
mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, array); mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, array);
mesh.SurfaceSetMaterial(0, mat);
for (var i = 0; i < materials.Count; i++)
{
var m = modelFile.Materials[i];
if (m.Slot == poly.Data)
{
mesh.SurfaceSetMaterial(poly.Index, materials[i]);
break;
}
}
}
var meshInstance = new MeshInstance3D { Mesh = mesh }; var meshInstance = new MeshInstance3D { Mesh = mesh };
AddChild(meshInstance); AddChild(meshInstance);