You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

118 lines
4.2 KiB

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<Vector3> vertices;
public List<int> indices;
public List<Vector3> normals;
public List<Vector2> 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<Vector3>();
var indices = new List<int>();
var normals = new List<Vector3>();
var uvs = new List<Vector2>();
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;
}
}
}