- Home /

# Custom Mesh Vector3's not normalizing

Hello all. I've just started playing around with Unity3d and decided to try my hand at generating an icosphere. I've got it mostly working, but it still needs some refining and streamlining (anything over three iterations takes an insanely large amount of time). The problem I'm running into is that the initial twelve vertices of the sphere are not normalizing like the rest of the sphere:

I ran into this problem before when I tried this out in plain c#, and doing Vector3.Normalize() solved it (if I remember correctly). That does not seem to be working here though.

Has anyone come across this before / have any ideas on how to fix it?

Thanks in advance.

Here is the code for the icosphere, I hope you can follow it, it was my first pass:

```
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
[RequireComponent (typeof (MeshCollider))]
[RequireComponent (typeof (MeshFilter))]
[RequireComponent (typeof (MeshRenderer))]
public class Icosphere : MonoBehaviour {
//The radius of the sphere is handled by the mesh scale
public int refinements = 0;
int index;
private Dictionary<Int64, int> middlePointIndexCache;
private List<Vector3> verticesList; //temporary holder for all vertices lists
private Vector3[] finalVertices; //holder for the final array of vertices
private int[] finalTriangles; //holder for the final array of triangle indexes
Mesh mesh;
//mesh.vertices is a Vector3[]
//mesh.triangles is an int[]
public void log(string s){
Debug.Log (s);
}
//struct to hold each face's set of vertices.
private struct TriangleIndices{
public int v1;
public int v2;
public int v3;
public TriangleIndices(int v1, int v2, int v3){
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
}
}
public void Rebuild(){
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter==null){
//Debug.LogError("MeshFilter not found!");
Debug.Log("MeshFilter not found!");
return;
}
//clear everything
this.index = 0;
this.middlePointIndexCache=new Dictionary<Int64, int>();
this.verticesList = new List<Vector3>();
//Generate a vector list
float t = (float)((1.0f + Mathf.Sqrt(5.0f)) / 2.0f);
//add each base vector to the temporary vertices list. relates to mesh.vertices
this.verticesList.Add(new Vector3(-1, t, 0));
this.verticesList.Add(new Vector3(1, t, 0));
this.verticesList.Add(new Vector3(-1, -t, 0));
this.verticesList.Add(new Vector3(1, -t, 0));
this.verticesList.Add(new Vector3(0, -1, t));
this.verticesList.Add(new Vector3(0, 1, t));
this.verticesList.Add(new Vector3(0, -1, -t));
this.verticesList.Add(new Vector3(0, 1, -t));
this.verticesList.Add(new Vector3(t, 0, -1));
this.verticesList.Add(new Vector3(t, 0, 1));
this.verticesList.Add(new Vector3(-t, 0, -1));
this.verticesList.Add(new Vector3(-t, 0, 1));
foreach(var vect in verticesList){
vect.Normalize();
}
//upodate the index values so that new vertices made during refinement
//will correspond to the appropriate index point in teh vertex list.
index+=12;
mesh = meshFilter.sharedMesh;
if (mesh == null){
meshFilter.mesh = new Mesh();
mesh = meshFilter.sharedMesh;
}
mesh.Clear();
mesh.RecalculateNormals();
//A list to temporarily hold face traingles. - relates to mesh.Triangles
List<TriangleIndices> faces = new List<TriangleIndices>();
// 5 faces around point 0
faces.Add(new TriangleIndices(0, 11, 5));
faces.Add(new TriangleIndices(0, 5, 1));
faces.Add(new TriangleIndices(0, 1, 7));
faces.Add(new TriangleIndices(0, 7, 10));
faces.Add(new TriangleIndices(0, 10, 11));
// 5 adjacent faces
faces.Add(new TriangleIndices(1, 5, 9));
faces.Add(new TriangleIndices(5, 11, 4));
faces.Add(new TriangleIndices(11, 10, 2));
faces.Add(new TriangleIndices(10, 7, 6));
faces.Add(new TriangleIndices(7, 1, 8));
// 5 faces around point 3
faces.Add(new TriangleIndices(3, 9, 4));
faces.Add(new TriangleIndices(3, 4, 2));
faces.Add(new TriangleIndices(3, 2, 6));
faces.Add(new TriangleIndices(3, 6, 8));
faces.Add(new TriangleIndices(3, 8, 9));
// 5 adjacent faces
faces.Add(new TriangleIndices(4, 9, 5));
faces.Add(new TriangleIndices(2, 4, 11));
faces.Add(new TriangleIndices(6, 2, 10));
faces.Add(new TriangleIndices(8, 6, 7));
faces.Add(new TriangleIndices(9, 8, 1));
//refine the triangles
for(int i = 0; i<refinements; i++){
int j=0;
List<TriangleIndices> faces2 = new List<TriangleIndices>();
foreach(var tri in faces){
//replace the triangle with four traingles
//log ("Triange: v1: " + tri.v1 + ", v2: " + tri.v2 + ", v3: " + tri.v3);
//log ("tri: " + tri.v1 + "," + tri.v2 + "," + tri.v3);
int a = getMiddlePoint(tri.v1, tri.v2);
int b = getMiddlePoint(tri.v2, tri.v3);
int c = getMiddlePoint(tri.v3, tri.v1);
//log ("New Face "+j+": " + a + "," + b + "," + c);
faces2.Add(new TriangleIndices(tri.v1, a, c));
faces2.Add(new TriangleIndices(tri.v2, b, a));
faces2.Add(new TriangleIndices(tri.v3, c, b));
faces2.Add(new TriangleIndices(a,b,c));
j++;
}
faces = faces2;
}//end for(int i)
//now add all the triangles to the mesh
int numFaces = faces.Count;
int numVertices = verticesList.Count;
int ind = 0;
//log("number of faces on the icosphere:" + numFaces);
//log("Number of Vertices in Icosphere:" + numVertices);
finalTriangles = new int[numFaces*3];
finalVertices = new Vector3[numVertices];
//convert the list<> to an array[]
verticesList.CopyTo(finalVertices);
mesh.vertices = finalVertices;
foreach(var vert in verticesList){
log ("Vertex " + ind + ": "+ mesh.vertices[ind].x + "," +mesh.vertices[ind].y + "," +mesh.vertices[ind].z);
ind++;
}
//add each triangle vertex set to mesh.triangles.
ind=0;
foreach(var tri in faces){
//log ("mesh vertices: " + index);
finalTriangles[ind]=tri.v1;
finalTriangles[ind+1]=tri.v2;
finalTriangles[ind+2]=tri.v3;
ind+=3;
}
mesh.triangles = finalTriangles;
mesh.RecalculateNormals();
ind=0;
foreach(var vert in mesh.vertices){
log ("Vertex " + index + ": "+ mesh.vertices[ind].x + "," +mesh.vertices[ind].y + "," +mesh.vertices[ind].z);
ind++;
}
mesh.RecalculateBounds();
mesh.Optimize();
}
private int getMiddlePoint(int p1, int p2){
//check to make sure we don't already have the point
bool firstisSmaller = p1 < p2;
//log ("first is smaller: " + firstisSmaller + " | "+ p1 + ", " + p2);
Int64 smallerIndex = firstisSmaller ? p1 : p2;
Int64 greaterIndex = firstisSmaller ? p2 : p1;
Int64 key = (smallerIndex << 32) + greaterIndex;
int ret;
if(this.middlePointIndexCache.TryGetValue(key, out ret)){
//log ("ret: " + ret);
return ret;
}
//if it is not in the cache, calculate it
Vector3 point1 = verticesList[p1];
Vector3 point2 = verticesList[p2];
Vector3 middle = new Vector3( (point1.x + point2.x)/2.0f,
(point1.y + point2.y)/2.0f,
(point1.z + point2.z)/2.0f);
//addVertex makes sure that the point is on unit sphere
int i = addVertex(middle);
//log ("i: " + i);
//store item and return index
this.middlePointIndexCache.Add(key,i);
return i;
}
private int addVertex(Vector3 p){
double length = Mathf.Sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
verticesList.Add(new Vector3((float)(p.x/length), (float)(p.y/length), (float)(p.z/length)));
return index++;
}
void Start () {
}
// Update is called once per frame
void Update () {
//put code that handles LOD here
}
}
```

Posting code might help us help you. You can edit your question and use the 'format' button (010/101)

**Answer** by Bunny83
·
Aug 22, 2012 at 07:27 PM

Eric is right, but the solution is also wrong ;) It would work when verticesList were an array of Vector3s. A generic List just provides an indexer to access it's elements. This indexer is a special kind of property, so it consists of a get and a set method. When using a List with a value type (like Vector3) you will get a copy of the actual Vector3. So calling Normalize() will normalize the copy but then just throws it away.

This "should" work:

```
for (var i = 0; i < verticesList.Count; i++)
{
verticesList[i] = verticesList[i].normalized;
}
```

Or if you prefer to use Normalize()

```
for (var i = 0; i < verticesList.Count; i++)
{
Vector3 tmp = verticesList[i];
tmp.Normalize();
verticesList[i] = tmp;
}
```

*edit*

Since the length of the base verts is always the same, you could even do that:

```
float mult = 1.0f / Mathf.Sqrt(1 + t * t);
this.verticesList.Add(new Vector3(-1*mult, t*mult, 0));
this.verticesList.Add(new Vector3( 1*mult, t*mult, 0));
this.verticesList.Add(new Vector3(-1*mult, -t*mult, 0));
//[...]
```

I used the first one and it worked perfectly... I knew that too... To be honest, I feel a little stupid XD

Thank you so much!

**Answer** by Eric5h5
·
Aug 20, 2012 at 08:54 PM

You can't do this in C#:

```
foreach(var vect in verticesList){
vect.Normalize();
}
```

Unlike Unityscript, a foreach loop in C# is essentially read-only. So you can do this instead:

```
for (var i = 0; i < verticesList.Count; i++) {
verticesList[i].Normalize();
}
```

As far as speed goes, if you know or can calculate the number of items in the arrays that will be needed ahead of time, you'd be better off using arrays instead of Lists.

@Eric5h5 I switched it to the for loop, but it's staying the same '-_-

Well, the vertices are normalized now anyway. ;) I guess the problem is elsewhere.

@Eric5h5 Hmm, even after normalizing is, the base vertex points (the combinations of 1, t and 0) are 1, 1.618034, 0 (respectively). This, at least to me, suggests that they still aren't being normalized. (I thought that with a normalized vector all parts would be less than 1)

It would be interesting what Unityscript would produce in this case ;). I think i have to try it. Be right back...

... No, it doesn't work in UnityScript either due to the indexer.

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.