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