Files
Ultimate-Fishing-Simulator-…/Assets/Scripts/Assembly-CSharp/MeshBaker.cs
2026-03-04 09:37:33 +08:00

176 lines
4.7 KiB
C#

using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class MeshBaker : MonoBehaviour
{
private struct PointWithUV
{
public Vector3 pos;
public Vector2 uv;
public Color color;
public float dist;
}
public Mesh mesh;
[Range(0f, 98f)]
public int sliceIndex;
[Range(64f, 256f)]
public int resolution = 64;
[Range(0f, 0.1f)]
public float sliceThreshold = 0.0044f;
[HideInInspector]
public List<float> slicesY;
[HideInInspector]
public Bounds bounds;
private Texture2D result;
public void Bake()
{
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i].y = Mathf.Max(vertices[i].y, 0f);
}
slicesY = new List<float>();
bounds = new Bounds
{
min = vertices[0],
max = vertices[0]
};
for (int j = 0; j < vertices.Length; j++)
{
bounds.Encapsulate(vertices[j]);
bool flag = false;
for (int k = 0; k < slicesY.Count; k++)
{
if (Mathf.Abs(slicesY[k] - vertices[j].z) < sliceThreshold)
{
flag = true;
break;
}
}
if (!flag)
{
slicesY.Add(vertices[j].z);
}
}
result = new Texture2D(resolution, slicesY.Count);
for (int l = 0; l < slicesY.Count; l++)
{
float sliceLength;
List<PointWithUV> slice = GetSlice(l, out sliceLength);
for (int m = 0; m < resolution; m++)
{
int n = 0;
float num;
for (num = (float)m / (float)(resolution - 1); n < slice.Count - 1 && !(slice[n].dist / sliceLength > num); n++)
{
}
float a = slice[n - 1].dist / sliceLength;
float b = slice[n].dist / sliceLength;
float t = Mathf.InverseLerp(a, b, num);
Vector3 vector = Vector3.Lerp(slice[n - 1].pos, slice[n].pos, t);
Vector3 vector2 = new Vector3((1f - num) * bounds.size.x + bounds.min.x, bounds.min.y, 0f);
Vector3 vector3 = vector - vector2;
float z = Mathf.Lerp(slice[n - 1].color.r, slice[n].color.r, t);
vector3 = new Vector3(vector3.x / (2f * bounds.size.x) + 0.5f, vector3.y / bounds.size.y, z);
result.SetPixel(m, l, new Color(vector3.x, vector3.y, vector3.z));
}
}
result.Apply();
byte[] bytes = result.EncodeToPNG();
string text = Application.dataPath + "/Artifacts/" + mesh.name + ".png";
File.WriteAllBytes(text, bytes);
Debug.Log("Texture file written at " + text);
}
private List<PointWithUV> GetSlice(int idx, out float sliceLength)
{
Vector3[] vertices = mesh.vertices;
Color[] colors = mesh.colors;
Vector2[] uv = mesh.uv;
List<PointWithUV> list = new List<PointWithUV>();
for (int i = 0; i < vertices.Length; i++)
{
vertices[i].y = Mathf.Max(vertices[i].y, 0f);
if (!(Mathf.Abs(slicesY[idx] - vertices[i].z) >= sliceThreshold))
{
Vector3 pos = vertices[i];
pos.z = 0f;
PointWithUV item = new PointWithUV
{
pos = pos
};
if (i < uv.Length)
{
item.uv = uv[i];
}
if (i < colors.Length)
{
item.color = colors[i];
}
list.Add(item);
}
}
list.Sort((PointWithUV pointWithUV, PointWithUV b) => (pointWithUV.uv.x > b.uv.x) ? 1 : (-1));
sliceLength = 0f;
Vector3 a = list[0].pos;
for (int num = 1; num < list.Count; num++)
{
Vector3 pos2 = list[num].pos;
sliceLength += Vector3.Distance(a, pos2);
a = pos2;
list[num] = new PointWithUV
{
pos = list[num].pos,
uv = list[num].uv,
color = list[num].color,
dist = sliceLength
};
}
return list;
}
private void OnDrawGizmos()
{
if (slicesY == null)
{
return;
}
sliceIndex = Mathf.Min(sliceIndex, slicesY.Count - 1);
Gizmos.color = Color.green;
Gizmos.DrawRay(base.transform.position + new Vector3(bounds.min.x, bounds.min.y, 0f), new Vector3(bounds.size.x, 0f, 0f));
Gizmos.DrawRay(base.transform.position + new Vector3(bounds.min.x, bounds.min.y, 0f), new Vector3(0f, bounds.size.y, 0f));
Gizmos.DrawRay(base.transform.position + new Vector3(bounds.max.x, bounds.max.y, 0f), -new Vector3(bounds.size.x, 0f, 0f));
Gizmos.DrawRay(base.transform.position + new Vector3(bounds.max.x, bounds.max.y, 0f), -new Vector3(0f, bounds.size.y, 0f));
float sliceLength;
List<PointWithUV> slice = GetSlice(sliceIndex, out sliceLength);
Vector3 vector = slice[0].pos;
for (int i = 1; i < slice.Count; i++)
{
Vector3 pos = slice[i].pos;
float num = slice[i].dist / sliceLength;
Gizmos.color = new Color(num, 0f, 0f);
if (num >= 0.8f && num <= 0.85f)
{
Gizmos.color = new Color(0f, 1f, 0f);
}
Gizmos.DrawLine(base.transform.position + vector, base.transform.position + pos);
Vector3 vector2 = new Vector3((1f - slice[i].dist / sliceLength) * bounds.size.x + bounds.min.x, bounds.min.y, 0f);
Gizmos.color = Color.blue;
Gizmos.DrawLine(base.transform.position + vector2, base.transform.position + pos);
vector = pos;
}
}
}