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; } public 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]; 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 + 2, index + v + 1 }); } index += verts.Count; } /* VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs); const vertexData = new VertexData(); vertexData.positions = positions; vertexData.indices = indices; vertexData.normals = normals; vertexData.uvs = uvs; return vertexData; */ return new VertexData() { vertices = positions, indices = indices, normals = normals, uvs = uvs, }; } /** * Creates the Mesh for a Goldberg Polyhedron which is made from 12 pentagonal and the rest hexagonal faces * @see https://en.wikipedia.org/wiki/Goldberg_polyhedron * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra/goldberg_poly * @param name defines the name of the mesh * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty * @param scene defines the hosting scene * @returns Goldberg mesh */ public 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) { var temp = n; n = m; m = temp; 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 goldberg = new Mesh(); //goldberg.name = name; var vertexData = CreateGoldbergVertexData(options, goldbergData); return vertexData; /* vertexData.applyToMesh(goldberg, options.updatable); goldberg.goldbergData.nbSharedFaces = geodesicData.sharedNodes; goldberg.goldbergData.nbUnsharedFaces = geodesicData.poleNodes; goldberg.goldbergData.adjacentFaces = geodesicData.adjacentFaces; goldberg.goldbergData.nbFaces = goldberg.goldbergData.nbSharedFaces + goldberg.goldbergData.nbUnsharedFaces; goldberg.goldbergData.nbFacesAtPole = (goldberg.goldbergData.nbUnsharedFaces - 12) / 12; for (var f = 0; f < geodesicData.vertex.Count; f++) { goldberg.goldbergData.faceCenters.push(Vector3.FromArray(geodesicData.vertex[f])); goldberg.goldbergData.faceCenters[f].x *= sizeX; goldberg.goldbergData.faceCenters[f].y *= sizeY; goldberg.goldbergData.faceCenters[f].z *= sizeZ; goldberg.goldbergData.faceColors.push(new Color4(1, 1, 1, 1)); } for (var f = 0; f < goldbergData.face.Count; f++) { var verts = goldbergData.face[f]; 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; var z = Vector3.Cross(ca, norm).normalized; //goldberg.goldbergData.faceXaxis.push(ca.normalize()); //goldberg.goldbergData.faceYaxis.push(norm); //goldberg.goldbergData.faceZaxis.push(z); } return goldberg; */ } } }