Normal Generating

Started by
18 comments, last by relsoft 18 years, 10 months ago
Hello, I have this framework as below:



#include <windows.h>
#include <gl/gl.h>

#include "icgSampleBox.h"
#include "vec3.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

icgSampleBox::icgSampleBox()
{
	m_afVertex[0][0]=-0.5f;
	m_afVertex[0][1]=-0.5f;
	m_afVertex[0][2]=0.5f;

	m_afVertex[1][0]=-0.5f;
	m_afVertex[1][1]=-0.5f;
	m_afVertex[1][2]=-0.5f;

	m_afVertex[2][0]=0.5f;
	m_afVertex[2][1]=-0.5f;
	m_afVertex[2][2]=-0.5f;

	m_afVertex[3][0]=0.5f;
	m_afVertex[3][1]=-0.5f;
	m_afVertex[3][2]=0.5f;

	m_afVertex[4][0]=-0.5f;
	m_afVertex[4][1]=0.5f;
	m_afVertex[4][2]=0.5f;
	
	m_afVertex[5][0]=-0.5f;
	m_afVertex[5][1]=0.5f;
	m_afVertex[5][2]=-0.5f;
	
	m_afVertex[6][0]=0.5f;
	m_afVertex[6][1]=0.5f;
	m_afVertex[6][2]=-0.5f;
	
	m_afVertex[7][0]=0.5f;
	m_afVertex[7][1]=0.5f;
	m_afVertex[7][2]=0.5f;

	m_afColour[0][0]=1.0f;
	m_afColour[0][1]=0.0f;
	m_afColour[0][2]=0.0f;

	m_afColour[1][0]=0.0f;
	m_afColour[1][1]=1.0f;
	m_afColour[1][2]=0.0f;

	m_afColour[2][0]=0.0f;
	m_afColour[2][1]=0.0f;
	m_afColour[2][2]=1.0f;

	m_afColour[3][0]=1.0f;
	m_afColour[3][1]=1.0f;
	m_afColour[3][2]=0.0f;

	m_afColour[4][0]=1.0f;
	m_afColour[4][1]=0.0f;
	m_afColour[4][2]=1.0f;

	m_afColour[5][0]=0.0f;
	m_afColour[5][1]=1.0f;
	m_afColour[5][2]=1.0f;

	m_auiFaces[0][0]=0;
	m_auiFaces[0][1]=1;
	m_auiFaces[0][2]=2;
	m_auiFaces[0][3]=3;
	
	m_auiFaces[1][0]=2;
	m_auiFaces[1][1]=6;
	m_auiFaces[1][2]=7;
	m_auiFaces[1][3]=3;

	m_auiFaces[2][0]=2;
	m_auiFaces[2][1]=1;
	m_auiFaces[2][2]=5;
	m_auiFaces[2][3]=6;
	
	m_auiFaces[3][0]=1;
	m_auiFaces[3][1]=0;
	m_auiFaces[3][2]=4;
	m_auiFaces[3][3]=5;
	
	m_auiFaces[4][0]=3;
	m_auiFaces[4][1]=7;
	m_auiFaces[4][2]=4;
	m_auiFaces[4][3]=0;
	
	m_auiFaces[5][0]=7;
	m_auiFaces[5][1]=6;
	m_auiFaces[5][2]=5;
	m_auiFaces[5][3]=4;
}


icgSampleBox::~icgSampleBox()
{

}


void icgSampleBox::apply()
{

	for(unsigned int i=0;i<6;i++)
	{
		glColor3fv(m_afColour);
		glBegin(GL_QUADS);

        glNormal3fv( 0.0f, 0.0f, 1.0f );      // Normal (I dont know how)

		glVertex3fv(m_afVertex[m_auiFaces[0]]);
		glVertex3fv(m_afVertex[m_auiFaces[1]]);
		glVertex3fv(m_afVertex[m_auiFaces[2]]);
		glVertex3fv(m_afVertex[m_auiFaces[3]]);	
		glEnd();
	}

}


I am trying to generate normal for my box (this above is a box) but I cant figure out how, I know that i should do like this : 1- get the direction of two faces 2- Calculate the cross product of the normalised direction vectors, this will give the vertex normal. I really stock to calculate this from the data I have. I need to find out how to do this here because I have another larger (very large) model that uses the same data structure. Thank you for your help.
OpenGl + C++
Advertisement
Quote:Original post by bargasteh
I am trying to generate normal for my box (this above is a box) but I cant figure out how, I know that i should do like this :
1- get the direction of two faces
2- Calculate the cross product of the normalised direction vectors, this will give the vertex normal.



That would not give you the face normal. Not the vertex normal.

To get the vertex normal:

1. Calculate face normal of a poly
2. average the normals that are found on adjacent faces that the normal is located.

BASIC source

To get the adjacent faces and the vertex normal:
FOR i = 1 TO Numvertex        xnormal! = 0        ynormal! = 0        znormal! = 0        FaceFound = 0    FOR j = 0 TO MaxPoly        IF Poly(j).P1 = i OR Poly(j).P2 = i OR Poly(j).P3 = i THEN            xnormal! = xnormal! + v(j).x            ynormal! = ynormal! + v(j).y            znormal! = znormal! + v(j).z            FaceFound = FaceFound + 1        'Face adjacent        END IF    NEXT j        xnormal! = xnormal! / FaceFound        ynormal! = ynormal! / FaceFound        znormal! = znormal! / FaceFound        v2(i).x = xnormal!        'Final vertex normal        v2(i).y = ynormal!        v2(i).z = znormal!    NEXT i


Hi.
Thank you for your code but I still couldnt figure out how to apply it to my code.

here i have a simpler and very general normal calculation method:

cross product on two vectors that lie on the polygon's plane (I think its very complete and general).

I have done this before but the problem is that I dont know how to do it with the above stucture.
how can i make a vector lets say from :

glVertex3fv(m_afVertex[m_auiFaces[0]]);
glVertex3fv(m_afVertex[m_auiFaces[1]]);
glVertex3fv(m_afVertex[m_auiFaces[2]]);

I tried this to get the direction of two vectors:

float d1 = vec3(m_afVertex[m_auiFaces[1]]) - m_afVertex[m_auiFaces[0]];
float d1 = vec3(m_afVertex[m_auiFaces[2]]) - m_afVertex[m_auiFaces[0]];

and then cross product and normalise the vector. but I dont know how to do it.

Do you know how?
OpenGl + C++
Quote:Original post by relsoft
*** Wrong Source Snippet Removed ***

For the n-th time : No.

That will not give you correct normals, period. Not to mention it runs in O(n*m).

This is a simple pseudocode to do it right:
for all vertices   set normal to zerofor all faces   compute face normal   add face normal to all 3 vertices (corners)   (optionaly you could use some weighting function based on face area or corner angle)for all vertices   normalize normal
You should never let your fears become the boundaries of your dreams.
Question:
what is the vector between these two points (Direction between them two points):

m_afVertex[0][0]=-0.5f;
m_afVertex[0][1]=-0.5f;
m_afVertex[0][2]=0.5f;

m_afVertex[1][0]=-0.5f;
m_afVertex[1][1]=-0.5f;
m_afVertex[1][2]=-0.5f;

second question: what is the difference between glVertex3fv and glVertex3f ?
what is that "v" for ?

thanks
OpenGl + C++
Quote:Original post by _DarkWIng_
Quote:Original post by relsoft
*** Wrong Source Snippet Removed ***

For the n-th time : No.

That will not give you correct normals, period. Not to mention it runs in O(n*m).

This is a simple pseudocode to do it right:
for all vertices   set normal to zerofor all faces   compute face normal   add face normal to all 3 vertices (corners)   (optionaly you could use some weighting function based on face area or corner angle)for all vertices   normalize normal

[smile] DarkWing, you've answered this so many times I think you should put a link to your answers in your sig or something man [lol]!!
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Well, instead of this can you please help me to sort this out for myself, because as you know its the most important thing that a 3D programmer should understand clearly.

Thank you
OpenGl + C++
What is going wrong here?

//----------------------------------for (int x = 0;x <= 5;x++){float a1 = m_afVertex[m_auiFaces[x][0]][0]; //xfloat a2 = m_afVertex[m_auiFaces[x][0]][1]; //yfloat a3 = m_afVertex[m_auiFaces[x][0]][2]; //zfloat b1 = m_afVertex[m_auiFaces[x][1]][0]; //xfloat b2 = m_afVertex[m_auiFaces[x][1]][1]; //yfloat b3 = m_afVertex[m_auiFaces[x][1]][2]; //zfloat c1 = m_afVertex[m_auiFaces[x][2]][0]; //xfloat c2 = m_afVertex[m_auiFaces[x][2]][1]; //yfloat c3 = m_afVertex[m_auiFaces[x][2]][2]; //z//vec3 d1 = vec3(b1-a1,b2-a2,b3-a3);//vec3 d2 = vec3(c1-a1,c2-a2,c3-a3);float x1 = b1-a1;float y1 = b2-a2;float z1 = b3-a3;float x2 = c1-a1;float y2 = c2-a2;float z2 = c3-a3;float length1 = sqrt ((x1*x1)+(y1*y1)+(z1*z1));float length2 = sqrt ((x2*x2)+(y2*y2)+(z2*z2));x1 = x1/length1; //normalisey1 = y1/length1;z1 = z1/length1;x2 = x2/length2;y2 = y2/length2;z2 = z2/length2;float crossx = (y2*z1) - (z2*y1);float crossy = (z2*x1) - (x2*z1);float crossz = (x2*y1) - (y2-x1);//result.set((y*v.getZ())-(z*v.getY()),(z*v.getX())-(x*v.getZ()),(x*v.getY())-(y*v.getX()));//vec3 d3 = d1.GetNormalised ().CrossProduct (d2.GetNormalised ());    m_afNormal[x][0]=crossx;	m_afNormal[x][1]=crossy;	m_afNormal[x][2]=crossz;}//---------------------------------------



I am trying to do the cross product of two vectors from my polygon. few sides of model look ok but the others are black. is there something wrong with this ?
OpenGl + C++
Going to take a wild stab at this... if some triangles are showing up black, it could mean that your model's face orientation (winding of vertices) is off.

Also, note that in the following code:

float crossx = (y2*z1) - (z2*y1);float crossy = (z2*x1) - (x2*z1);float crossz = (x2*y1) - (y2-x1);   // this is subtract -- SHOULD BE MULTIPLY



Additionally, I thought that the cross product was the other way around:

float crossx = (y1 * z2) - (z1 * y2);float crossy = (z1 * x2) - (x1 * z2);float crossz = (x1 * y2) - (y1 * x2);
Thank you so much, its working now :)
now I want to do smooth rendering, do you guys have any idea how? is it the average between two neighbour face normal?
It would be great to get smooth rendering!
OpenGl + C++

This topic is closed to new replies.

Advertisement