Sign in to follow this  
TheSeb

problem with per vertex normals computations

Recommended Posts

TheSeb    144
Hi, i am making a .3ds file loader and my normals are wrong. i multiply my normals with the transformation matrix of the .3ds file, i did not do the same with the vertices but it doen't change the normals values, i'll do it later. Can you check my function because i don't see the error particularly the main part which add normals then normalize. PS : do you why the meshes displayed are deformed/larger than under 3ds max ? what can i do for this ?
for (polyCounter = 0 ; polyCounter< myObjects[counterObj].nbPoly ; polyCounter++)
	{
	        //read face per face
		file.read((char*) &(myObjects[counterObj].myIndices[polyCounter][0]), sizeof (unsigned short int));
		file.read((char*) &(myObjects[counterObj].myIndices[polyCounter][1]), sizeof (unsigned short int));
		file.read((char*) &(myObjects[counterObj].myIndices[polyCounter][2]), sizeof (unsigned short int));
		file.read((char*) &(faceInfo), sizeof (short int));
	//	cout<<"face info "<<faceInfo<<endl ;

		int Va = myObjects[counterObj].myIndices[polyCounter][0] ;
		int Vb = myObjects[counterObj].myIndices[polyCounter][1] ;
		int Vc = myObjects[counterObj].myIndices[polyCounter][2] ;                                                                       
		

		float Vab[] = {(myObjects[counterObj].myVertices[Vb][0] - myObjects[counterObj].myVertices[Va][0]),
					(myObjects[counterObj].myVertices[Vb][1] - myObjects[counterObj].myVertices[Va][1]),
					(myObjects[counterObj].myVertices[Vb][2] - myObjects[counterObj].myVertices[Va][2])};

		float Vac[] = {(myObjects[counterObj].myVertices[Vc][0] - myObjects[counterObj].myVertices[Va][0]),
					(myObjects[counterObj].myVertices[Vc][1] - myObjects[counterObj].myVertices[Va][1]),
					(myObjects[counterObj].myVertices[Vc][2] - myObjects[counterObj].myVertices[Va][2])};
		
		float Vba[] = {(myObjects[counterObj].myVertices[Va][0] - myObjects[counterObj].myVertices[Vb][0]),
					(myObjects[counterObj].myVertices[Va][1] - myObjects[counterObj].myVertices[Vb][1]),
					(myObjects[counterObj].myVertices[Va][2] - myObjects[counterObj].myVertices[Vb][2])};

		float Vbc[] = {(myObjects[counterObj].myVertices[Vc][0] - myObjects[counterObj].myVertices[Vb][0]),
					(myObjects[counterObj].myVertices[Vc][1] - myObjects[counterObj].myVertices[Vb][1]),
					(myObjects[counterObj].myVertices[Vc][2] - myObjects[counterObj].myVertices[Vb][2])};

		float Vca[] = {(myObjects[counterObj].myVertices[Va][0] - myObjects[counterObj].myVertices[Vc][0]),
					(myObjects[counterObj].myVertices[Va][1] - myObjects[counterObj].myVertices[Vc][1]),
					(myObjects[counterObj].myVertices[Va][2] - myObjects[counterObj].myVertices[Vc][2])};

		float Vcb[] = {(myObjects[counterObj].myVertices[Vb][0] - myObjects[counterObj].myVertices[Vc][0]),
					(myObjects[counterObj].myVertices[Vb][1] - myObjects[counterObj].myVertices[Vc][1]),
					(myObjects[counterObj].myVertices[Vb][2] - myObjects[counterObj].myVertices[Vc][2])};
		
		switch (faceInfo)
		{
			case 0x3 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vac, Vbc) ;
				      break ;
			case 0x7 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vab, Vbc) ;
				      break ;
			case 0x6 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vab, Vbc) ;
				      break ;
			case 0x5 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vac, Vab) ;
				      break ;
			case 0x4 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vab, Vcb) ;
				      break ;
			case 0x2 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vca, Vbc) ;
				      break ;
			case 0x1 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vac, Vcb) ;
				      break ;
			case 0x0 :crossProduct(&myObjects[counterObj].perFaceNormals[polyCounter], Vba, Vcb) ;
				      break ;
		}
		normalize(&myObjects[counterObj].perFaceNormals[polyCounter]) ;
		
		//oFile2<<dec<<"angle "<<angle[polyCounter*3]<<" "<<angle[polyCounter*3+1]<<" "<<angle[polyCounter*3+2]<<endl ;
		
	}//fin de la boucle for
	
	cout<<"face info "<<hex<<faceInfo<<endl ;
	
	for (polyCounter = 0 ; polyCounter< myObjects[counterObj].nbVertices ; polyCounter++)
	{
		myObjects[counterObj].perVertexNormals[polyCounter][0] = 0 ;
		myObjects[counterObj].perVertexNormals[polyCounter][1] = 0 ;
		myObjects[counterObj].perVertexNormals[polyCounter][2] = 0 ;
	}
		
	for(nIndice=0 ; nIndice < myObjects[counterObj].nbVertices ; nIndice++)
	{
		for(i=0 ; i < myObjects[counterObj].nbPoly ; i++)
		{
			for(j=0 ; j< 3; j++)
			{
				if(myObjects[counterObj].myIndices[i][j]==nIndice)
				{
					myObjects[counterObj].perVertexNormals[nIndice][0] += myObjects[counterObj].perFaceNormals[i].x ;
					myObjects[counterObj].perVertexNormals[nIndice][1] += myObjects[counterObj].perFaceNormals[i].y ;
					myObjects[counterObj].perVertexNormals[nIndice][2] += myObjects[counterObj].perFaceNormals[i].z ;
				}
			}
		}
	}

	multiplyMatrix(myObjects[counterObj].localAxisMatrix, 
				   &myObjects[counterObj].perVertexNormals[0][0], 
				   &myObjects[counterObj].nbVertices) ;


//normalize
	for(counter=0 ; counter < myObjects[counterObj].nbVertices ; counter++)
	{
		normalize(&myObjects[counterObj].perVertexNormals[counter][0], 
				  &myObjects[counterObj].perVertexNormals[counter][1],
				  &myObjects[counterObj].perVertexNormals[counter][2]) ;
	}

	ofstream oFile("sortie3ds.txt");
	for(counter=0 ; counter < myObjects[counterObj].nbVertices ; counter++)
	{
		 oFile<<"par vertex "<<myObjects[counterObj].perVertexNormals[counter][0] <<" "
					<<myObjects[counterObj].perVertexNormals[counter][1] <<" "
					<<myObjects[counterObj].perVertexNormals[counter][2] <<endl ;
	}
cout.flush() ;
}

Share this post


Link to post
Share on other sites
S1CA    1418
I only skim-read your code, but: when transforming the normals with the object matrix, you should only be using the rotation part of the transform (the top-left 3x3 portion of the matrix).

Applying a translation to a normal is the wrong thing to do since it represents only direction rather than position.

1  0  0
0 1 0
0 0 1
Tx Ty Tz



As for why the objects appear larger than in Max: do you have the same projection and camera matrices set up as Max ? - if not, the mesh will look different.

Another possibilty is reading one of the transformation matrices wrongly from the Max file in such a way that you get some sort of shear/skew transform (interpreting a 3x4 matrix as a 4x3 could do that...)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this