override public void CalculateNormals()
{
base.CalculateNormals();
if (Indices.Count == 0)
return;
Normals.Clear();
Vector3[] sum = new Vector3[Vertices.Count];
Vector3 surfaceNormal;
Vector3 e1;
Vector3 e2;
int posInIndices = 0;
for (int index = 0; index < VerticesPerPolygon.Count; index++)
{
int verticesCount = VerticesPerPolygon[index];
for (int index0 = 0; index0 < verticesCount; index0++)
{
Vector3 vertex = Vector3.Invalid.Clone();
Vector3 previousVertex = Vector3.Invalid.Clone();
Vector3 nextVertex = Vector3.Invalid.Clone();
int indice = Indices[posInIndices];
vertex = Vertices[indice];
if (index0 == 0)
{
int previousIndice = Indices[posInIndices + verticesCount - 1];
previousVertex = Vertices[previousIndice];
int nextIndice = Indices[posInIndices + 1];
nextVertex = Vertices[nextIndice];
}
else if (index0 > 0 && index0 < verticesCount - 1)
{
int previousIndice = Indices[posInIndices - 1];
previousVertex = Vertices[previousIndice];
int nextIndice = Indices[posInIndices + 1];
nextVertex = Vertices[nextIndice];
}
else if (index0 == verticesCount - 1)
{
int previousIndice = Indices[posInIndices - 1];
previousVertex = Vertices[previousIndice];
int nextIndice = Indices[posInIndices - verticesCount + 1];
nextVertex = Vertices[nextIndice];
}
//---- Calculate the surface normal
e1 = previousVertex - vertex;
e2 = vertex - nextVertex;
surfaceNormal = e1.Cross(e2);
surfaceNormal.Normalize();
// Sum it at the vertex index
sum[indice] += surfaceNormal;
//---- next
posInIndices++;
}
}
for (int index = 0; index < Vertices.Count; index++)
{
sum[index].Normalize();
Normals.Add(sum[index]);
}
}
Calculate normals for a polygon - faces problem
Hi,
I'm trying to calculate the normals for a set of polygons... but I got a problem.
I calculate the normals and when I display theses normals they sounds correct :-(
You can see this on the first picture here :
http://picasaweb.google.com/viewon01/OpenGL#5391730635084390018
I don't know why my model sounds so "faceted" and that sometimes I got a face that looks strange !!
Take a look at :
http://picasaweb.google.com/viewon01/OpenGL#5391730633418058914
or
http://picasaweb.google.com/viewon01/OpenGL#5380203925050881714
Can you help me please ?
You can find my application at http://rs.codeplex.com
or ... here is the source code for the normals calculation :
Avoid crossposting. It's only been 15 hours since your last post.
A guess is that perhaps your polygons have bad vertices in them or something. Make sure not to use 3 vertices in a straight line, or 2 vertices with the exact same coordinates, when calculating the normal.
A guess is that perhaps your polygons have bad vertices in them or something. Make sure not to use 3 vertices in a straight line, or 2 vertices with the exact same coordinates, when calculating the normal.
Okay, I will...
I have this problem with other models...
Also, I have load theses models with 2 other applications and they sounds correct, but not in my version :-(
I have this problem with other models...
Also, I have load theses models with 2 other applications and they sounds correct, but not in my version :-(
I'm not 100% sure about what you're doing for non-triangular polygons. Could you try rendering a model that only has triangular faces?
Also, if the problem persists could you post a close up screenshot?
Also, if the problem persists could you post a close up screenshot?
Thanks,
This one is composed of triangles only :
http://picasaweb.google.com/viewon01/OpenGL#5380203925050881714
I don't know what is happening, even not sure it is due to the normals !
I have try to play with back-face culling too... but I got no result too :-(
Here is the code for the triangles (based on same concept):
This one is composed of triangles only :
http://picasaweb.google.com/viewon01/OpenGL#5380203925050881714
I don't know what is happening, even not sure it is due to the normals !
I have try to play with back-face culling too... but I got no result too :-(
Here is the code for the triangles (based on same concept):
override public void CalculateNormals() { base.CalculateNormals(); if (Indices.Count == 0) return; Normals.Clear(); //---- Vector3[] sum = new Vector3[Vertices.Count]; for (int jj = 0; jj < Indices.Count / 3; jj++) { int indice1 = Indices[jj * 3]; int indice2 = Indices[jj * 3 + 1]; int indice3 = Indices[jj * 3 + 2]; Vector3 v1 = Vertices[indice1]; Vector3 v2 = Vertices[indice2]; Vector3 v3 = Vertices[indice3]; // Calculate the surface normal Vector3 e1 = Vertices[indice1] - Vertices[indice2]; Vector3 e2 = Vertices[indice2] - Vertices[indice3]; Vector3 surfaceNormal = e1.Cross(e2); surfaceNormal.Normalize(); // Sum it at the vertex index sum[indice1] += surfaceNormal; sum[indice2] += surfaceNormal; sum[indice3] += surfaceNormal; } for (int index = 0; index < Vertices.Count; index++) { sum[index].Normalize(); Normals.Add(sum[index]); } }
It looks like maybe the normals are correct, but are being applied to the wrong vertices on each triangle.
Of course,
You can even download the complete source code at :
http://rs.codeplex.com
Here is the OpenGL code to display the polygon (class OGLRenderer.cs):
Here is the code that calculate the normals of the polygon (class PolygonGeometry.cs)
Thanks
You can even download the complete source code at :
http://rs.codeplex.com
Here is the OpenGL code to display the polygon (class OGLRenderer.cs):
private void RenderPolygonGeometry(PolygonGeometry polygon) { int indiceIndex = 0; for (int index0 = 0; index0 < polygon.VerticesPerPolygon.Count; index0++) { int count = polygon.VerticesPerPolygon[index0]; Gl.glBegin(Gl.GL_POLYGON); for (int index = 0; index < count; index++) { int indice = polygon.Indices[indiceIndex]; Vector3 vertex = polygon.Vertices[indice]; Vector3 normal = polygon.Normals[indice]; Gl.glVertex3d(vertex.x, vertex.y, vertex.z); Gl.glNormal3d(normal.x, normal.y, normal.z); indiceIndex++; } Gl.glEnd(); } }
Here is the code that calculate the normals of the polygon (class PolygonGeometry.cs)
override public void UpdateNormals() { base.UpdateNormals(); if (Indices.Count == 0 || Normals.Count > 0) // Already calculated return; Normals.Clear(); Vector3[] sum = new Vector3[Vertices.Count]; int posInIndices = 0; for (int index = 0; index < VerticesPerPolygon.Count; index++) { int verticesCount = VerticesPerPolygon[index]; for (int index0 = 0; index0 < verticesCount; index0++) { Vector3 vertex = Vector3.Invalid.Clone(); Vector3 previousVertex = Vector3.Invalid.Clone(); Vector3 nextVertex = Vector3.Invalid.Clone(); int indice = Indices[posInIndices]; vertex = Vertices[indice]; if (index0 == 0) { int previousIndice = Indices[posInIndices + verticesCount - 1]; previousVertex = Vertices[previousIndice]; int nextIndice = Indices[posInIndices + 1]; nextVertex = Vertices[nextIndice]; } else if (index0 > 0 && index0 < verticesCount - 1) { int previousIndice = Indices[posInIndices - 1]; previousVertex = Vertices[previousIndice]; int nextIndice = Indices[posInIndices + 1]; nextVertex = Vertices[nextIndice]; } else if (index0 == verticesCount - 1) { int previousIndice = Indices[posInIndices - 1]; previousVertex = Vertices[previousIndice]; int nextIndice = Indices[posInIndices - verticesCount + 1]; nextVertex = Vertices[nextIndice]; } //---- Calculate the surface normal Vector3 surfaceNormal = CalculateNormal(previousVertex, vertex, nextVertex); // Sum it at the vertex index if (!surfaceNormal.IsInvalid) { sum[indice] += surfaceNormal; } //---- next posInIndices++; } } for (int index = 0; index < Vertices.Count; index++) { sum[index].Normalize(); Normals.Add(sum[index]); } }
Thanks
I can't see anything wrong with your code. I think the way forward is to check your assumptions and try to narrow down the problem. A few ideas:
1. make sure it really is the normals that cause the 'faceted' appearence. To do this, I'd try rendering with all the normals set to (1, 0, 0), or something like that, which ought to appear evenly lit.
2. try turning off lighting and textures, and instead colouring the vertices according to some function of 'indice', for example ((indice % 2) * 255, ((indice / 2) % 2) * 255, ((indice / 4) % 2) * 255). We should be able to see if the vertices are being shared correctly.
Does anybody have any other suggestions?
1. make sure it really is the normals that cause the 'faceted' appearence. To do this, I'd try rendering with all the normals set to (1, 0, 0), or something like that, which ought to appear evenly lit.
2. try turning off lighting and textures, and instead colouring the vertices according to some function of 'indice', for example ((indice % 2) * 255, ((indice / 2) % 2) * 255, ((indice / 4) % 2) * 255). We should be able to see if the vertices are being shared correctly.
Does anybody have any other suggestions?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement