#c# #unity3d #geometry #mesh
#c# #unity3d #геометрия #сетка
Вопрос:
Привет, я использую Unity и C # вместе с средством визуализации сетки и фильтром для имитации фрагмента 16*16*256
(фрагмента Minecraft). Следуя следующему видео в качестве руководства.
У меня есть 3 константы :
Globals.CHUNK_X
(сокращено до W)
Globals.CHUNK_Y
(H)
Globals.CHUNK_Z
(D)
У меня также есть функция Globals.c3to1(x, y, z)
, которая преобразует 3d-индекс в 1d-индекс в (W 1)*(H 1)*(D 1)
массиве вершин, возвращая следующее (H 1) * (W 1) * z (W 1) * y x
.
Я расположил свои вершины в 1d массиве измерений (W 1)*(H 1)*(D 1)
, называемых vertices
такими, что vertices[c3to1(x, y, z)] = (x, y, z)
. Теперь, когда у меня есть свои вершины, как мне собрать все треугольники в массив. Я создал цикл for, с которым можно согласиться.
/*How the array of vertices were created.*/
vertices = new Vector3[(Globals.CHUNK_X 1) * (Globals.CHUNK_Y 1) * (Globals.CHUNK_Z 1)];
for (int z = 0; z <= Globals.CHUNK_Z; z ) {
for (int y = 0; y <= Globals.CHUNK_Y; y ) {
for (int x = 0; x <= Globals.CHUNK_X; x ) {
int index = Globals.c3to1(x, y, z);
vertices[index] = new Vector3(x, y, z);
}
}
}
/*How do I go about doing this triangles array*/
triangles = new int[36 * (Globals.CHUNK_X 1) * (Globals.CHUNK_Y 1) * (Globals.CHUNK_Z 1)];
for (int z = 0; z < Globals.CHUNK_Z; z ) { //For each aisle
for (int y = 0; y < Globals.CHUNK_Y; y ) { //For each row
for (int x = 0; x < Globals.CHUNK_X; x ) { //For each column
for (int i = 0, index = 0; i < 6; i ) { //For each 6 faces
for (int j = 0; j < 6; j , index ) { //For each 6 points of each face
//triangles[36 * Globals.c3to1(x, y, z) index] = ?;
}
}
}
}
}
Для тех, кто задается вопросом, почему вершины 17*17*257
вместо 16*16*256
этого являются bc, в каждой строке, столбце и проходе есть дополнительная вершина (2 смежных куба имеют 3 вершины на соединенном ребре, 3 имеют 4, 4 имеют 5 и так далее).
Комментарии:
1. Вы уверены, что хотите это сделать? Это около 2 миллионов треугольников, где большинство из них все равно не видны. Чего вы пытаетесь достичь? Можно ли отображать только треугольники на поверхности?
2. @NicoSchertler Я думаю, что в Unity есть какая-то выбраковка, потому что я пытался делать это раньше, но в итоге 14*16*256 вместо того , чтобы 16*16*256 , но все же удалось получить более 2000 кадров в секунду. Я думаю, что Unity не заботится о невидимых треугольниках, но это только я.
Ответ №1:
Во многих случаях люди просто задают кубические треугольники вручную. Добавление циклов не очень выгодно, потому что они будут очень короткими, а логика становится довольно запутанной:
int nextIndex = 0;
// index offsets that are equivalent to increasing x/y/z by 1
int stepX = Globals.c3to1(1, 0, 0);
int stepY = Globals.c3to1(0, 1, 0);
int stepZ = Globals.c3to1(0, 0, 1);
for (int z = 0; z < Globals.CHUNK_Z; z ) { //For each aisle
for (int y = 0; y < Globals.CHUNK_Y; y ) { //For each row
for (int x = 0; x < Globals.CHUNK_X; x ) { //For each column
int baseVertex = Globals.c3to1(x, y, z);
// front face
triangles[nextIndex ] = baseVertex;
triangles[nextIndex ] = baseVertex stepY;
triangles[nextIndex ] = baseVertex stepX;
triangles[nextIndex ] = baseVertex stepX;
triangles[nextIndex ] = baseVertex stepY;
triangles[nextIndex ] = baseVertex stepX stepY;
// repeat equivalently for other faces
}
}
}
Комментарии:
1. Хорошо, я понял, каков ваш ответ, спасибо за это, однако я получаю дополнительный ряд удлиненных треугольников на обратной стороне одной из граней. Я прикреплю изображения здесь 1 мин.
2. Вот изображения проблемы. Вперед: imgur.com/a/2A5SJ4z В обратном направлении: imgur.com/a/OjxUYey
3. Вероятно, один из ваших индексов отключен. Если вы не нашли, какой именно, закомментируйте по одному треугольнику за раз и посмотрите, когда проблема исчезнет.
Ответ №2:
Этот код не ваш, но он иллюстрирует то, что вы хотите знать. Итак, если вы пройдетесь по этому коду, вы найдете свой ответ.
Об этом коде: Это скрипт на C # для создания цилиндрической сетки во время выполнения
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cylinder : MonoBehaviour
{
[SerializeField]
private float radius = 2.0f;
[SerializeField]
private float height = 4.0f;
[SerializeField]
private int VerticalSubdivisions = 10;
[SerializeField]
private int HorizontalSubdivisions = 4;
private void Start()
{
CreateCylinder();
}
void CreateCylinder()
{
Vector3[] vertices = new Vector3[VerticalSubdivisions * (HorizontalSubdivisions 2) 2];
float delta_angle = Mathf.PI * 2 / VerticalSubdivisions;
float delta_height = height / (HorizontalSubdivisions 1);
for (int j = 0; j < (HorizontalSubdivisions 2); j )
for (int i = 0; i < VerticalSubdivisions; i )
{
vertices[1 i j * VerticalSubdivisions] = new Vector3(Mathf.Cos(delta_angle * i) * radius, delta_height * j - height * 0.5f, Mathf.Sin(delta_angle * i) * radius);
}
vertices[0] = new Vector3(0, -height * 0.5f, 0);
vertices[vertices.Length - 1] = new Vector3(0, height * 0.5f, 0);
int[] triangles = new int[6 * VerticalSubdivisions * (HorizontalSubdivisions 1) VerticalSubdivisions * 2 * 3];
for (int i = 0; i < (VerticalSubdivisions - 1); i )
{
triangles[i * 3 0] = 0;
triangles[i * 3 1] = i 1;
triangles[i * 3 2] = i 2;
}
triangles[(VerticalSubdivisions - 1) * 3 0] = 0;
triangles[(VerticalSubdivisions - 1) * 3 1] = 1 VerticalSubdivisions - 1;
triangles[(VerticalSubdivisions - 1) * 3 2] = 1;
int lower_cap_tris_offset = 3 * VerticalSubdivisions;
for (int j = 0; j < (HorizontalSubdivisions 1); j )
{
for (int i = 0; i < VerticalSubdivisions; i )
{
int index = lower_cap_tris_offset j * VerticalSubdivisions * 6 6 * i;
triangles[index 0] = 1 i VerticalSubdivisions * j;
triangles[index 1] = 1 VerticalSubdivisions * (j 1) i;
triangles[index 2] = 1 VerticalSubdivisions * (j 1) i 1;
triangles[index 3] = triangles[index 2];
triangles[index 4] = 1 i VerticalSubdivisions * j 1;
triangles[index 5] = 1 i VerticalSubdivisions * j;
}
int __index = lower_cap_tris_offset j * VerticalSubdivisions * 6 6 * (VerticalSubdivisions - 1);
triangles[__index 0] = 1 VerticalSubdivisions - 1 VerticalSubdivisions * j;
triangles[__index 1] = 1 VerticalSubdivisions * (j 1) VerticalSubdivisions - 1;
triangles[__index 2] = 1 VerticalSubdivisions * (j 1);
triangles[__index 3] = triangles[__index 2];
triangles[__index 4] = 1 VerticalSubdivisions * j;
triangles[__index 5] = 1 VerticalSubdivisions - 1 VerticalSubdivisions * j;
}
for (int i = 0; i < VerticalSubdivisions - 1; i )
{
int index = 3 * VerticalSubdivisions VerticalSubdivisions * 6 * (HorizontalSubdivisions 1);
triangles[index i * 3 0] = 1 VerticalSubdivisions * (HorizontalSubdivisions 1) i;
triangles[index i * 3 1] = vertices.Length - 1;
triangles[index i * 3 2] = 1 VerticalSubdivisions * (HorizontalSubdivisions 1) i 1;
}
int _index = 3 * VerticalSubdivisions VerticalSubdivisions * 6 * (HorizontalSubdivisions 1) (VerticalSubdivisions - 1) * 3;
triangles[_index 0] = 1 VerticalSubdivisions * (HorizontalSubdivisions 1) VerticalSubdivisions - 1;
triangles[_index 1] = vertices.Length - 1;
triangles[_index 2] = 1 VerticalSubdivisions * (HorizontalSubdivisions 1);
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
Надеюсь, это поможет вам!