Sign in to follow this  
jswill100

OpenGL C++ STL Map for vertex normals. Help?

Recommended Posts

Hello all, Am having a small problem - right now I am exporting a large scene from 3ds into opengl using the .3ds format - and this does not contain any vertex normal information so i need to calculate it myself. Before you see some code you should know my vertices (and vert normals) are organised into vector<Vector3f> where Vector3f is my own structure for a vertex. The verts are organised so that there are repeated vertex, i.e. verts 1,2,3 are for the first triangle, and 3,4,5 are for the second, but none, 1 or 2 of these vertices may in reality be the same as 1,2 or 3. I started out using an extremely extremely time consuming method as below
void calculateSharedVerts(vector<Vector3f>& verts, vector<Vector3f>& vertNormals)
{
Vector3f temp;


        //here I set the intial vertex normals to that of the face normal for the face they belong to. 
	for(int i=0; i< verts.size(); i+=3)
	{
		temp.calculateNormal_2(verts[i], verts[i+1], verts[i+2]);

		vertNormals.push_back(temp);
		vertNormals.push_back(temp);
		vertNormals.push_back(temp);
	}


        //Now I loop through and whenever we find a shared vertex, we add the face normals from both
	for(int i=0; i< verts.size(); i++)
	{

		for(int j=0; j< verts.size(); j++)
		{
			if(i!=j)
			{
				if(verts[i]==verts[j])
				{
					vertNormals[i]+= vertNormals[j];
				}
			}
			
		}
	}

        //normalise the results
	for(int i=0; i< vertNormals.size(); i++)
	{
		vertNormals[i].normalise();
	}
}

The above worked entirely correctly, but because of the size of my scene, even just computing these normals once and writing to a file to be read later takes hours on end and so I searched for a better way of doing it. I realised I could use the stl Map so that whenever I was addressing a shared vertex, I only needed to use that one value so no looping to find shared verts is required. Because the other definition I use for Vector3f "less than" does not meet the requirements of "strict weak ordering" I define a new comparison function vect3fCompare to use. Basically the normals are coming out far from correct and was hoping someone might be able to give me some insight into what I might be doing wrong here.
	bool vect3fCompare(Vector3f p1, Vector3f p2) {

	Vector3f zero(0,0,0);

	//the below SHOULD satisfy strict weak ordering, which I read was is nessecery for this to work, defined by
		//1) a<a is false 
		//2) equality given by (!(a<b) && !(b<a)) - i.e. less than can be used to determine equality
		//3) If a<b and b<c, then a<c must be true.
	if(p1.distance(zero) < p2.distance(zero))
		return true;



	return false;
 }	

void addNormals(vector<Vector3f>& verts, vector<Vector3f>& vertNormals) {
	
		map<Vector3f, Vector3f, bool(*)(Vector3f, Vector3f)> myMap(vect3fCompare);

		Vector3f temp;

		//calculate the face normal, and set each vert to that face normal.
		for(int i=0; i< verts.size(); i+=3)
		{
			temp.calculateNormal_2(verts[i], verts[i+1], verts[i+2]);

			vertNormals.push_back(temp);
			vertNormals.push_back(temp);
			vertNormals.push_back(temp);
		}

		Vector3f zero(0,0,0);

                //fill it up with 0s.
		for(int i=0; i< verts.size(); i++)
			myMap[verts[i]] = zero;


		//for every shared vertex, myMap will now collect all the proper face normals together to make individual vert normals.
		for(int i=0; i< verts.size(); i++)
		{
			myMap[verts[i]] += vertNormals[i];
		}

                //now we loop back through, setting each vertNormal to the value calculated in the map.
		for(int i=0; i< verts.size(); i++)
			vertNormals[i] = myMap[verts[i]]; //addition of all verts same as verts[i]
			
                //and finally normalise
		for(int i=0; i< vertNormals.size(); i++)
		{
			vertNormals[i].normalise();
		}
}



Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this