Вы заинтересовали меня своим вопросом, и я думаю, что у меня есть решение, которое вы искали.Вот как мы можем создать желаемую топологию:
1) Начнем с шестиугольника.Почему шестиугольник, а не другая форма?Потому что шестиугольник - единственная магическая форма с радиусом, равным длине его стороны.Мы назовем этот радиус R .Теперь мы попытаемся создать форму, которая напоминает круг и состоит из треугольников с длиной стороны приблизительно R .
2) Теперь представим несколько концентрических кругов с радиусом R, 2R, 3R и т. Д. - чем больше, тем выше разрешение.
3) Круг с номером 1 имеет радиус R .Теперь мы заменим этот круг шестиугольником с радиусом R .
4) Теперь мы добавим больше узлов на секундукруг, чтобы расширить наш шестиугольник.Какова окружность круга с номером N ?Это 2PiRN .Теперь мы хотим разделить его на X ребер длиной примерно R .Следовательно, X = 2PiN , что приблизительно равно 6N .Итак, мы разделим первый круг на 6 ребер (шестиугольник), второй на 12, затем 18, 24 и т. Д.
5) Теперь у нас есть много кругов, разделенных на ребра.Теперь нам нужно соединить ребра в треугольники.Как мы строим треугольники между кругом N (внешний) и N-1 (внутренний)?Внешний круг имеет на 6 ребер больше, чем внутренний.Если бы у них было одинаковое количество вершин, мы могли бы связать их с квадратами.Но они этого не делают.Итак, мы все же попытаемся построить квады, но для каждого N построенных нами квадратов нам нужно будет добавить 1 треугольник.Каждый квад использует 2 вершины из внутренней и 2 вершины из внешней окружности.Каждый треугольник использует 2 вершины из внешнего круга и только 1 из внутреннего, таким образом компенсируя избыток вершин.
6) И теперь, наконец,есть несколько проверенных примеров кода, который делает то, что вам нужноОн сгенерирует окружность с однородной топологией, с центральной точкой в начале координат и радиусом 1, разделенной на подкруги * разрешения.Он может использовать некоторую незначительную оптимизацию производительности (пока это выходит за рамки), но в целом он должен делать свою работу.
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class UniformCirclePlane : MonoBehaviour {
public int resolution = 4;
// Use this for initialization
void Start() {
GetComponent<MeshFilter>().mesh = GenerateCircle(resolution);
}
// Update is called once per frame
void Update() {
}
// Get the index of point number 'x' in circle number 'c'
static int GetPointIndex(int c, int x) {
if (c < 0) return 0; // In case of center point
x = x % ((c + 1) * 6); // Make the point index circular
// Explanation: index = number of points in previous circles + central point + x
// hence: (0+1+2+...+c)*6+x+1 = ((c/2)*(c+1))*6+x+1 = 3*c*(c+1)+x+1
return (3 * c * (c + 1) + x + 1);
}
public static Mesh GenerateCircle(int res) {
float d = 1f / res;
var vtc = new List<Vector3>();
vtc.Add(Vector3.zero); // Start with only center point
var tris = new List<int>();
// First pass => build vertices
for (int circ = 0; circ < res; ++circ) {
float angleStep = (Mathf.PI * 2f) / ((circ + 1) * 6);
for (int point = 0; point < (circ + 1) * 6; ++point) {
vtc.Add(new Vector2(
Mathf.Cos(angleStep * point),
Mathf.Sin(angleStep * point)) * d * (circ + 1));
}
}
// Second pass => connect vertices into triangles
for (int circ = 0; circ < res; ++circ) {
for (int point = 0, other = 0; point < (circ + 1) * 6; ++point) {
if (point % (circ + 1) != 0) {
// Create 2 triangles
tris.Add(GetPointIndex(circ - 1, other + 1));
tris.Add(GetPointIndex(circ - 1, other));
tris.Add(GetPointIndex(circ, point));
tris.Add(GetPointIndex(circ, point));
tris.Add(GetPointIndex(circ, point + 1));
tris.Add(GetPointIndex(circ - 1, other + 1));
++other;
} else {
// Create 1 inverse triange
tris.Add(GetPointIndex(circ, point));
tris.Add(GetPointIndex(circ, point + 1));
tris.Add(GetPointIndex(circ - 1, other));
// Do not move to the next point in the smaller circle
}
}
}
// Create the mesh
var m = new Mesh();
m.SetVertices(vtc);
m.SetTriangles(tris, 0);
m.RecalculateNormals();
m.UploadMeshData(true);
return m;
}
}
Окончательный результат: