I want to generate a cube and subdivide each face of the cube 4 times, in this way a cube of 6 faces will have 24 faces. I'm am trying doing this in Unity3d but its giving me Out of Memory Exception when I try executing it. I think it may be due to some bad efficient code, but I think I'm missing something because I'm trying to see if I can make it more efficient and I don't really see nothing very bad.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class sphereMesh : MonoBehaviour
{
// Start is called before the first frame update
Mesh mesh;
List<Vector3> vertices = new List<Vector3>();
List<int> triangulos = new List<int>();
public int numeroSubdivisiones = 1;
static Vector3[] faceCubes = {
new Vector3(1, 1, 1), //0
new Vector3(-1, 1, 1), //1
new Vector3(-1, -1, 1), //2
new Vector3(1, -1, 1), //3
new Vector3(-1, 1, -1), //4
new Vector3(1, 1, -1), //5
new Vector3(1, -1, -1), //6
new Vector3(-1, -1, -1) //7
};
static int[][] facetriangulos = {
// Cara trasera
new int[]{0,1,2,3},
// Cara derecha
new int[]{5,0,3,6},
// Cara frontal
new int[]{4,5,6,7},
// Cara izquierda
new int[]{1,4,7,2},
// Cara arriba
new int[]{5,4,1,0},
// Cara abajo
new int[]{3,2,7,6},
};
void MakeFace(int dir)
{
vertices.AddRange(faceVertices(dir));
int vCount = vertices.Count;
triangulos.Add(vCount - 4);
triangulos.Add(vCount - 4 + 1);
triangulos.Add(vCount - 4 + 2);
triangulos.Add(vCount - 4);
triangulos.Add(vCount - 4 + 2);
triangulos.Add(vCount - 4 + 3);
}
void MakeCube()
{
vertices = new List<Vector3>();
triangulos = new List<int>();
for (int i = 0; i <6; i++)
{
MakeFace(i);
}
}
// Funcion que crea una cara de vertices
public static Vector3[] faceVertices(int dir)
{
Vector3[] fv = new Vector3[4];
for (int i = 0; i < fv.Length; i++)
{
// La direccion y la posicion del array
fv[i] = faceCubes[facetriangulos[dir][i]];
}
return fv;
}
// Modifica la lista de vertices y la actualiza
// De forma que un cuadrado da lugar a otros cuatro cuadrados
// T --> Top, D --> Down, L --> Left, R --> Right
// v --> Vertice
void subdividirCuadrado(Vector3 vTL, Vector3 vTR, Vector3 vDL, Vector3 vDR)
{
Vector3 vT = vT = Vector3.Lerp(vTR, vTL, 0.5f);
Vector3 vD = vD = Vector3.Lerp(vDR, vDL, 0.5f);
Vector3 vR = vR = Vector3.Lerp(vTR,vDR, 0.5f);
Vector3 vL = vL = Vector3.Lerp(vTL,vDL, 0.5f);
Vector3 vCenter = Vector3.Lerp(vR, vL, 0.5f);
int size = vertices.Count;
vertices.AddRange(new List<Vector3> {vT, vD, vL, vR, vTL, vTR, vDL, vDR, vCenter});
int tT = size + 0;
int tD = size + 1;
int tL = size + 2;
int tR = size + 3;
int tTL = size + 4;
int tTR = size + 5;
int tDL = size + 6;
int tDR = size + 7;
int tCenter = size + 8;
triangulos.AddRange(new List<int> {tL, tTL, tT});
triangulos.AddRange(new List<int> {tL, tT, tCenter});
triangulos.AddRange(new List<int> {tCenter, tT, tTR});
triangulos.AddRange(new List<int> {tCenter, tTR, tR});
triangulos.AddRange(new List<int> {tDL, tL, tCenter});
triangulos.AddRange(new List<int> {tDL, tCenter, tD});
triangulos.AddRange(new List<int> {tD, tCenter, tR});
triangulos.AddRange(new List<int> {tD, tR, tDR});
}
void subCubo()
{
for(int j = 0; j < numeroSubdivisiones; j++)
{
Debug.Log("AAAAA" + vertices.Count);
for (int i = 0; i < vertices.Count; i += 4)
{
subdividirCuadrado(vertices[i], vertices[i+1], vertices[i+2], vertices[i+3]);
/*
mesh.vertices[i][0] = mesh.vertices[i][0]/i;
mesh.vertices[i][1] = mesh.vertices[i][1]/i;
mesh.vertices[i][2] = mesh.vertices[i][2]/i;
mesh.vertices[i+1][0] = mesh.vertices[i+1][0]/i+1;
mesh.vertices[i+1][1] = mesh.vertices[i+1][1]/i+1;
mesh.vertices[i+1][2] = mesh.vertices[i+1][2]/i+1;
mesh.vertices[i+2][0] = mesh.vertices[i+2][0]/i+2;
mesh.vertices[i+2][1] = mesh.vertices[i+2][1]/i+2;
mesh.vertices[i+2][2] = mesh.vertices[i+2][2]/i+2;
mesh.vertices[i+3][0] = mesh.vertices[i+3][0]/i+3;
mesh.vertices[i+3][1] = mesh.vertices[i+3][1]/i+3;
mesh.vertices[i+3][2] = mesh.vertices[i+3][2]/i+3;
*/
}
}
}
void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
}
void Start()
{
MakeCube();
subCubo();
UpdateMesh();
}
// Update is called once per frame
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices.ToArray();
mesh.triangles = triangulos.ToArray();
mesh.RecalculateNormals();
}
}
I think this is infinity loop:
for (int i = 0; i < vertices.Count; i += 4)
{
subdividirCuadrado(vertices[i], vertices[i+1], vertices[i+2], vertices[i+3]);
You keep going through the loop until i is bigger than count of items in vertices. During each iteration i is increased by 4, but there are 9 new items in vertices:
vertices.AddRange(new List<Vector3> {vT, vD, vL, vR, vTL, vTR, vDL, vDR, vCenter});
Therefore i is never bigger than vertices.count and thus the loop is infinite.