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.

174 lines
6.7 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;
}
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<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];
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;
*/
}
}
}