- Home /
Setting triangles failing
So, I'm modifying the sphere generation script found on the Unity wikia so that I can generate spheres with more than 65000 vertices (by splitting apart the mesh). However, I have run into an issue. The code below works fine (including creating a child object and applying the mesh) up until I input latitude and longitude values that would generate a sphere over 65000 vertices. Once it reaches a number higher than that, the debugger is telling me I am trying to assign triangles to non-existant vertices (some indices are referencing out of bounds vertices). I know what this error means, but I don't know what is wrong in the code - if I had to guess, though, it's just some bad math.
Here's the code:
 IEnumerator BuildPlanet()
 {
     noise = new Perlin();
     //Mesh mesh = new Mesh();
     MeshFilter filter = gameObject.AddComponent< MeshFilter >();
     //Mesh mesh = filter.mesh;
     //mesh.Clear();
     //Mesh[] mesh = new Mesh[];
     float radius = 1f;
     // Longitude |||
     int nbLong = 360;
     // Latitude ---
     int nbLat = 184;
     
     #region Vertices
     Vector3[] vertices = new Vector3[(nbLong+1) * nbLat + 2];
     //print (vertices.Length);
     float _pi = Mathf.PI;
     float _2pi = _pi * 2f;
     int obj = Mathf.CeilToInt((float)vertices.Length/65000);
 
     vertices[0] = Vector3.up * radius;
     //for(int m = 0; m < obj; m++)
     //{
 
         for( int lat = 0; lat < nbLat; lat++ )
         {
             float a1 = _pi * (float)(lat+1) / (nbLat+1);
             float sin1 = Mathf.Sin(a1);
             float cos1 = Mathf.Cos(a1);
             
             for( int lon = 0; lon <= nbLong; lon++ )
             {
                 float a2 = _2pi * (float)(lon == nbLong ? 0 : lon) / nbLong;
                 float sin2 = Mathf.Sin(a2);
                 float cos2 = Mathf.Cos(a2);
                 
                 vertices[ lon + lat * (nbLong + 1) + 1] = new Vector3( sin1 * cos2, cos1, sin1 * sin2 ) * radius;
                 //vertices[ lon + lat * (nbLong + 1) + 1] = vertices[ lon + lat * (nbLong + 1) + 1].normalized*(float)(100+noise.GetValue(sin1*cos2, cos1, sin1*cos2)*2);
                 //vertices.normalized*(float)(100+noise.GetValue(pos.x, pos.y, pos.z)*2);
             }
         }
     //}
     vertices[vertices.Length-1] = Vector3.up * -radius;
 
     #endregion
     
     #region Normales        
     Vector3[] normales = new Vector3[vertices.Length];
     for( int n = 0; n < vertices.Length; n++ )
         normales[n] = vertices[n].normalized;
     #endregion
     
     #region UVs
     Vector2[] uvs = new Vector2[vertices.Length];
     uvs[0] = Vector2.up;
     uvs[uvs.Length-1] = Vector2.zero;
     for( int lat = 0; lat < nbLat; lat++ )
         for( int lon = 0; lon <= nbLong; lon++ )
             uvs[lon + lat * (nbLong + 1) + 1] = new Vector2( (float)lon / nbLong, 1f - (float)(lat+1) / (nbLat+1) );
     #endregion
     
     #region Triangles
     int nbFaces = vertices.Length;
     int nbTriangles = nbFaces * 2;
     int nbIndexes = nbTriangles * 3;
     int[] triangles = new int[ nbIndexes ];
     
     //Top Cap
     int i = 0;
     for( int lon = 0; lon < nbLong; lon++ )
     {
         triangles[i++] = lon+2;
         triangles[i++] = lon+1;
         triangles[i++] = 0;
     }
     
     //Middle
     for( int lat = 0; lat < nbLat - 1; lat++ )
     {
         for( int lon = 0; lon < nbLong; lon++ )
         {
             int current = lon + lat * (nbLong + 1) + 1;
             int next = current + nbLong + 1;
             
             triangles[i++] = current;
             triangles[i++] = current + 1;
             triangles[i++] = next + 1;
             
             triangles[i++] = current;
             triangles[i++] = next + 1;
             triangles[i++] = next;
         }
     }
     
     //Bottom Cap
     for( int lon = 0; lon < nbLong; lon++ )
     {
         triangles[i++] = vertices.Length - 1;
         triangles[i++] = vertices.Length - (lon+2) - 1;
         triangles[i++] = vertices.Length - (lon+1) - 1;
     }
 
     #endregion
 
     for(int m = 0; m < obj; m++)
     {
         int v = m*65000;
         Mesh mesh = new Mesh();
         mesh.Clear();
         GameObject gos = new GameObject("GO");
 
         Vector3[] verts = new Vector3[Mathf.Clamp (vertices.Length-v, 3, 65000)];
         Vector3[] norms = new Vector3[verts.Length];
         Vector2[] uv = new Vector2[verts.Length];
         int[] tris = new int[verts.Length*6];
 
 
         for(int a = 0; a < verts.Length; a++)
         {
             verts[a] = vertices[a+v];
         }
         for(int b = 0; b < norms.Length; b++)
         {
             norms[b] = normales[b+v];
         }
         for(int c = 0; c < uv.Length; c++)
         {
             uv[c] = uvs[c+v];
         }
         for(int d = 0; d < tris.Length; d++)
         {
             tris[d] = triangles[d+v];
         }
 
 
         mesh.vertices = verts;
         mesh.normals = norms;
         mesh.uv = uv;
         mesh.triangles = tris;
     
         mesh.RecalculateBounds();
         mesh.Optimize();
         gos.AddComponent<MeshFilter>();
         gos.AddComponent<MeshRenderer>();
         gos.AddComponent<MeshCollider>();
         gos.GetComponent<MeshFilter>().mesh = mesh;
         gos.GetComponent<MeshCollider>().sharedMesh = mesh;
         gos.transform.parent = transform;
         gos.GetComponent<MeshRenderer>().material = transform.GetComponent<MeshRenderer>().material;
 
     }
 
     yield return null;
 }
Permitting the question because it doesn't violate any rules, but I would not expect pro bono help with complex math-heavy algorithms.
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
               
 
			 
                