thief-mission-viewer/project/code/TMV/Model.cs

100 lines
3.1 KiB
C#
Raw Normal View History

2024-08-18 10:14:30 +00:00
using System;
2024-08-17 19:53:16 +00:00
using System.Collections.Generic;
using System.IO;
2024-08-17 19:53:16 +00:00
using Godot;
using Godot.Collections;
using KeepersCompound.LGS;
using KeepersCompound.TMV.UI;
namespace KeepersCompound.TMV;
public partial class Model : Node3D
{
public override void _Ready()
{
var modelSelector = GetNode<Control>("%ModelSelector") as ModelSelector;
modelSelector.LoadModel += BuildModel;
}
private void BuildModel(string rootPath, string modelPath)
{
foreach (var node in GetChildren())
{
node.QueueFree();
}
var modelFile = new ModelFile(modelPath);
if (modelFile == null)
{
GD.Print($"Failed to load model file: {modelPath}");
return;
2024-08-17 19:53:16 +00:00
}
// TODO: Remove this disgusting hack
var baseDir = ProjectSettings.GlobalizePath($"user://objects/tmp");
var options = new EnumerationOptions
{
MatchCasing = MatchCasing.CaseInsensitive,
RecurseSubdirectories = true,
};
2024-08-18 10:14:30 +00:00
var textures = new List<ImageTexture>();
foreach (var material in modelFile.Materials)
{
var paths = Directory.GetFiles(baseDir, material.Name, options);
if (paths.IsEmpty()) continue;
var texture = TextureLoader.LoadTexture(paths[0]);
var saveName = material.Name.GetBaseName() + ".png";
texture.GetImage().SavePng(ProjectSettings.GlobalizePath($"user://debug/{saveName}"));
2024-08-18 10:14:30 +00:00
textures.Add(texture);
}
2024-08-18 10:14:30 +00:00
var mat = new StandardMaterial3D
2024-08-17 19:53:16 +00:00
{
2024-08-18 10:14:30 +00:00
AlbedoTexture = textures[0]
};
2024-08-17 19:53:16 +00:00
2024-08-18 10:14:30 +00:00
// TODO: Support multiple materials and colour based materials
var surfaceData = new MeshSurfaceData();
2024-08-17 19:53:16 +00:00
foreach (var poly in modelFile.Polygons)
{
2024-08-18 10:14:30 +00:00
var vertices = new List<Vector3>();
var normal = modelFile.Normals[poly.Normal].ToGodotVec3();
var uvs = new List<Vector2>();
for (var i = 0; i < poly.VertexCount; i++)
2024-08-17 19:53:16 +00:00
{
2024-08-18 10:14:30 +00:00
var vertex = modelFile.Vertices[poly.VertexIndices[i]];
vertices.Add(vertex.ToGodotVec3());
if (i < poly.UvIndices.Length)
{
var uv = modelFile.Uvs[poly.UvIndices[i]];
uvs.Add(new Vector2(uv.X, uv.Y));
}
else
{
var uv = (i % 4) switch
{
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);
}
2024-08-17 19:53:16 +00:00
}
2024-08-18 10:14:30 +00:00
surfaceData.AddPolygon(vertices, normal, uvs, uvs);
}
var array = surfaceData.BuildSurfaceArray();
2024-08-17 19:53:16 +00:00
var mesh = new ArrayMesh();
mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, array);
2024-08-18 10:14:30 +00:00
mesh.SurfaceSetMaterial(0, mat);
2024-08-17 19:53:16 +00:00
var meshInstance = new MeshInstance3D { Mesh = mesh };
AddChild(meshInstance);
}
}