I am trying to build a cube as a composition of many quads, with each quad being composed of two triangles. All the triangles have the same size. I am dong this (instead of drawing a single cube with just six faces) in order to have better lighting effects.
The final cube itself looks perfect however when I calculate the normals the final result looks weird. Really weird as you can see in the picture.
That's how I am calculating the normals:
For every triangle:
calculate the normal by doing the cross product. The result is then normalized.
For each vertex of this triangle:
Assign the same normal to all the three vertices
if a normal was previously assigned to the same vertex, sum it with the newly calculated value. Keep track on how many times that vertex is "shared"
Once the loop over the vertex is finished, divide each component of the normal vector with the number of times the vertex was shared.
In this picture the front face of the cube:
Also, I am adding some code:
//in vertices(which is an ArrayList<Float[]>) I have all my vertices.
public ArrayList<Float[]> getNormals()
{
normals = new ArrayList<Float[]>();
LinkedHashMap<String, ArrayList<Float[]>> map = new LinkedHashMap<String, ArrayList<Float[]>>();
for(int i=0; i<(vertices.size()-2); i=i+3)
{
float x1 = vertices.get(i)[0]; float y1 = vertices.get(i)[1]; float z1 = vertices.get(i)[2];
float x2 = vertices.get(i+1)[0]; float y2 = vertices.get(i+1)[1]; float z2 = vertices.get(i+1)[2];
float x3 = vertices.get(i+2)[0]; float y3 = vertices.get(i+2)[1]; float z3 = vertices.get(i+2)[2];
float[] U;
float[] V;
U = new float[]{x1-x2, y1-y2, z1-z2};
V = new float[]{x1-x3, y1-y3, z1-z3};
Float[] normal = new Float[]
{
(U[1] * V[2]) - (U[2]-V[1]),
(U[2] * V[0]) - (U[0]-V[2]),
(U[0] * V[1]) - (U[1]-V[0])
};
normal = normalize(normal);
ArrayList<Float[]> newList = new ArrayList<Float[]>();
newList.add(normal);
ArrayList<Float[]> list = map.get(x1+" "+y1+" "+z1);
if(list==null) map.put(x1+" "+y1+" "+z1, newList);
else{
list.add(normal);
map.put(x1+" "+y1+" "+z1, list);
}
list = map.get(x2+" "+y2+" "+z2);
if(list==null) map.put(x2+" "+y2+" "+z2, newList);
else{
list.add(normal);
map.put(x2+" "+y2+" "+z2, list);
}
list = map.get(x3+" "+y3+" "+z3);
if(list==null) map.put(x3+" "+y3+" "+z3, newList);
else{
list.add(normal);
map.put(x3+" "+y3+" "+z3, list);
}
}
//averaging normals
for(int i=0; i<vertices.size(); i++)
{
String key = vertices.get(i)[0]+" "+vertices.get(i)[1]+" "+vertices.get(i)[2];
Float[] newNormal = new Float[]{0f,0f,0f};
ArrayList<Float[]> lists = map.get(key);
for(int j=0; j<lists.size(); j++)
{
newNormal[0] += lists.get(j)[0];
newNormal[1] += lists.get(j)[1];
newNormal[2] += lists.get(j)[2];
}
newNormal[0] /= ((float)lists.size());
newNormal[1] /= ((float)lists.size());
newNormal[2] /= ((float)lists.size());
normals.add(normalize(newNormal));
}
return normals;
}