Archived

This topic is now archived and is closed to further replies.

clutch

Calculating normals for the idiot (me!)

Recommended Posts

Alright, so I am trying to render a .ply file. I can get the vertices and indices out of the file no problem and have a nice spinning bunny. But then I want to go back and populate a normal for each vertice. Here is the code I use. v1,v2 and v3 are all indicies to the index array which are then indicies to the vertex array. Here is the code:
void CPlyReader::normal(int v1, int v2, int v3)
{
	float length;
	float qx, qy, qz, px, py, pz;
	float nx, ny, nz;

	qx = varr[iarr[v3]] - varr[iarr[v2]];
	qy = varr[iarr[v3]+1] - varr[iarr[v2]+1];
	qz = varr[iarr[v3]+2] - varr[iarr[v2]+2];
	px = varr[iarr[v1]] - varr[iarr[v2]];
	py = varr[iarr[v1]+1] - varr[iarr[v2]+1];
	pz = varr[iarr[v1]+2] - varr[iarr[v2]+2];
	nx = py*qz - pz*qy;
	ny = qz*px - qx*pz;
	nz = py*qx - px*qy;

	length = sqrt(nx*nx + ny*ny + nz*nz);

	narr[iarr[v1]] = nx / length;
	narr[iarr[v2]] = nx / length;
	narr[iarr[v3]] = nx / length;

	narr[iarr[v1]+1] = ny / length;
	narr[iarr[v2]+1] = ny / length;
	narr[iarr[v3]+1] = ny / length;

	narr[iarr[v1]+2] = nz / length;
	narr[iarr[v2]+2] = nz / length;
	narr[iarr[v3]+2] = nz / length;
}
Now I realize I have a lot of faces on this thing and a lot of shared vertices, but I figured I should get a good approximation of the normals doing them as face rather than vertex normals. What I end upwith is a pretty spotted bunny though. Here is a link to a screen shot: Should I be figuring out per vertex normals? I just didn't think the bunny would look this bad. Thanks for any help. Clutch [edit] - Fixed IMG tag [edited by - clutch on October 24, 2003 4:38:12 PM]

Share this post


Link to post
Share on other sites
fixed img (src, not href...)


looks like messed cw/ccw triangles/polygons, but i dont know the fileformat and cant say if the information is missing, not needed or whatever (3ds for example has a seperate array with cw/ccw informations (IMHO))...


edit: ohh and this is wrong (IMHO :D):
nx = py*qz - pz*qy;
ny = qz*px - qx*pz;
nz = py*qx - px*qy;

should be
nx = py*qz - pz*qy;
ny = pz*qx - px*qz;
nz = px*qy - py*qx;


T2k

[edited by - T2k on October 24, 2003 4:26:21 PM]

Share this post


Link to post
Share on other sites
The .ply file is explained at http://www.cc.gatech.edu/projects/large_models/ply.html.

But changing the code that you mentioned made no difference (as I had made the change to the wrong way in the first place, forogt to change it back). I appreciate the help though and I think I will look at some other ply rendering tools now too to see how they handle it.

Share this post


Link to post
Share on other sites
ehm this may sound stupid, but:
quote:

qx = varr[iarr[v3]] - varr[iarr[v2]];
qy = varr[iarr[v3]+1] - varr[iarr[v2]+1];
qz = varr[iarr[v3]+2] - varr[iarr[v2]+2];



are not the vertices you want,
your varr contains the vertices, and the iarr contains the indexes, these indexes are grouped not the verices so you will have to move the ''+1'' and ''+2'' into the iarr clamps, additionaly you will have to group them into groups of 3 elements:
qy = varr[iarr[v3*3+1]] - varr[iarr[v2*3+1]];

or you do a struct (pseudocode, you will have to use correct types...):
struct FACE{
int index1, index2, index3;
} *faces= iarr;
and then you can go through the faces by
faces[facenum].index1 ...


T2k

Share this post


Link to post
Share on other sites
Interesting observervation, but it isn''t right. The index arrary points to the first coordinate of a vertex. So a face is made of 3 vertexes, in this case the first one being 1541,2416,1103. This means I should get 1541, 1542, and 1543 from the vertex array to define that point. Same with the other points. If I do what you are suggesting (which was my first incarnation of this program) it will fail with memory errors due to the fact that I go out of the bounds of the index array.

Would posting the rest of the code help?

Also I went through a debugging procedure (should have done this first, my apologies) and what I expected to be X is in the Z position, Y is in the following X and Z is in the following Y. So it looks like I have an offset of 2.

I will work this into my code now.

By the way thanks for the help, I hate when it feels like I am stuck. I need to understand vectors better.

Clutch

Share this post


Link to post
Share on other sites
hehe sry for posting nonsens (for my excuse its 23:30 here and ive worked to long on my GDArena-Bot )

quote:
Also I went through a debugging procedure (should have done this first, my apologies) and what I expected to be X is in the Z position, Y is in the following X and Z is in the following Y. So it looks like I have an offset of 2.


could also be that the file-format stores the axis in a differnet order, you object is drawn correctly (it looks so, solid no holes, no overlapping triangles...) so i dont think there is a offset...

have you try''d to draw the normals? just to see if they face in the correct direction, ...


ok ive thought about your last post and my last post and this line:
qy = varr[iarr[v3]+1] - varr[iarr[v2]+1];

i will repeat myself just to see what iam actually constructing
varr is an array of vertices, you mentioned (did you? ) that a vertex contains 3 values, i think float, something like
struct VERTEX{
float comps[3];
}

when you want to get a vertex you do varr[index], this will give you the first component, but now you try to acces the second component by varr[index+1], but thats the first component of the next vertex, to get the next component you would do a second index like varr[index][1] or somethin else.
the next thing i dont get is why is there a dual indexing, usualy you will have a vertexlist, then a indexlist where all 3 following components belong to one face, but its maybe so and your v1,v2,v3 are in row...

!!!shuting down brain, need sleep :D!!!


T2k

Share this post


Link to post
Share on other sites
My vertex array is a big one dimensional float array

float[] varr;

So, no structures, just one flat array that has tightly packed array data. Easier to pass this off to the OpenGL vertex array list.

Clutch

Share this post


Link to post
Share on other sites