89 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			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;
 | 
						|
    }
 | 
						|
} |