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

89 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using Godot;
using GArray = Godot.Collections.Array;
namespace KeepersCompound.TMV;
public class MeshSurfaceData
{
const string MATERIAL_PATH = "res://project/materials/base.tres";
public bool Empty { get; private set; }
private readonly Texture _texture;
private readonly List<Vector3> _vertices = new();
private readonly List<Vector3> _normals = new();
private readonly List<int> _indices = new();
private readonly List<Vector2> _textureUvs = new();
private readonly List<Vector2> _lightmapUvs = new();
public MeshSurfaceData(Texture texture)
{
_texture = texture;
Empty = true;
}
public void TransformLightmapUvs(int start, int end, Func<Vector2, Vector2> f)
{
for (var i = start; i < end; i++)
{
_lightmapUvs[i] = f(_lightmapUvs[i]);
}
}
// TODO: Guard against empty polygons being added
public (int, int) AddPolygon(
List<Vector3> vertices,
Vector3 normal,
List<Vector2> textureUvs,
List<Vector2> lightmapUvs)
{
Empty = false;
var vertexCount = vertices.Count;
var indexOffset = _vertices.Count;
_vertices.AddRange(vertices);
for (var i = 0; i < vertexCount; i++)
{
_normals.Add(normal);
}
// Simple triangulation. Polys are always convex so we can just do a fan
for (int j = 1; j < vertexCount - 1; j++)
{
_indices.Add(indexOffset);
_indices.Add(indexOffset + j);
_indices.Add(indexOffset + j + 1);
}
_textureUvs.AddRange(textureUvs);
_lightmapUvs.AddRange(lightmapUvs);
var end = _lightmapUvs.Count;
var start = end - lightmapUvs.Count;
return (start, end);
}
public GArray BuildSurfaceArray()
{
var array = new GArray();
array.Resize((int)Mesh.ArrayType.Max);
array[(int)Mesh.ArrayType.Vertex] = _vertices.ToArray();
array[(int)Mesh.ArrayType.Normal] = _normals.ToArray();
array[(int)Mesh.ArrayType.Index] = _indices.ToArray();
array[(int)Mesh.ArrayType.TexUV] = _textureUvs.ToArray();
array[(int)Mesh.ArrayType.TexUV2] = _lightmapUvs.ToArray();
return array;
}
public Material BuildMaterial(Texture lightmapTexture)
{
var material = ResourceLoader.Load<ShaderMaterial>(MATERIAL_PATH).Duplicate() as ShaderMaterial;
material.SetShaderParameter("texture_albedo", _texture);
material.SetShaderParameter("lightmap_albedo", lightmapTexture);
return material;
}
}