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.
118 lines
4.2 KiB
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;
|
|
}
|
|
}
|
|
|
|
} |