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 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(); 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 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 GetSlice(int idx, out float sliceLength) { Vector3[] vertices = mesh.vertices; Color[] colors = mesh.colors; Vector2[] uv = mesh.uv; List list = new List(); 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 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; } } }