using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; namespace Metamesh { public class GoldbergBuilder { public class GoldbergVertexDataOption { public float size = 1; public float sizeX = 1; public float sizeY = 1; public float sizeZ = 1; }; public class GoldbergCreationOption : GoldbergVertexDataOption { public int m; public int n; } public class VertexData { public List vertices; public List indices; public List normals; public List uvs; } private static VertexData CreateGoldbergVertexData(GoldbergVertexDataOption options, PolyhedronData goldbergData) { var size = options.size; var sizeX = options.sizeX;// || size || 1; var sizeY = options.sizeY;// || size || 1; var sizeZ = options.sizeZ;// || size || 1; var positions = new List(); var indices = new List(); var normals = new List(); var uvs = new List(); var minX = float.MaxValue; var maxX = float.MinValue; var minY = float.MaxValue; var maxY = float.MinValue; for (var v = 0; v < goldbergData.vertex.Count; v++) { minX = Mathf.Min(minX, goldbergData.vertex[v].x * sizeX); maxX = Mathf.Max(maxX, goldbergData.vertex[v].x * sizeX); minY = Mathf.Min(minY, goldbergData.vertex[v].y * sizeY); maxY = Mathf.Max(maxY, goldbergData.vertex[v].y * sizeY); } var index = 0; for (var f = 0; f < goldbergData.face.Count; f++) { var verts = goldbergData.face[f]; if (verts[0] >= goldbergData.vertex.Count || verts[1] >= goldbergData.vertex.Count || verts[2] >= goldbergData.vertex.Count) { Debug.LogWarning($"{verts[0]} | {verts[1]} | {verts[2]} > {goldbergData.vertex.Count}"); continue; } var a = goldbergData.vertex[verts[0]]; var b = goldbergData.vertex[verts[2]]; var c = goldbergData.vertex[verts[1]]; var ba = b - a; var ca = c - a; var norm = Vector3.Cross(ca, ba).normalized; for (var v = 0; v < verts.Count; v++) { normals.Add(norm); var pdata = goldbergData.vertex[verts[v]]; positions.Add(new Vector3(pdata[0] * sizeX, pdata[1] * sizeY, pdata[2] * sizeZ)); var vCoord = (pdata[1] * sizeY - minY) / (maxY - minY); uvs.Add(new Vector2((pdata[0] * sizeX - minX) / (maxX - minX), vCoord)); } for (var v = 0; v < verts.Count - 2; v++) { indices.AddRange(new int[] { index, index + v + 1, index + v + 2 }); } index += verts.Count; } return new VertexData() { vertices = positions, indices = indices, normals = normals, uvs = uvs, }; } public static VertexData CreateGoldberg(GoldbergCreationOption options) { var size = options.size; var sizeX = options.sizeX;// || size || 1; var sizeY = options.sizeY;// || size || 1; var sizeZ = options.sizeZ;// || size || 1; var m = options.m;// || 1; var n = options.n;// || 0; if (n > m) { (n, m) = (m, n); Debug.LogWarning("n > m therefore m and n swapped"); } var primTri = new PrimaryIsoTriangle(); primTri.Build(m, n); var geodesicData = GeodesicData.BuildGeodesicData(primTri); var goldbergData = geodesicData.ToGoldbergPolyhedronData(); var vertexData = CreateGoldbergVertexData(options, goldbergData); return vertexData; } } }