vertex unsharing - triangle list question

Started by
4 comments, last by juddo 13 years, 7 months ago
hello!

i've stopped myself several times from posting a thread here regarding my unclear and miss understanding of model vertex sharing, hoping i'd find the answer i was after sooner or later... but i simply can't find a clear answer for what im having trouble understanding anywhere.

the thick of it is;

i'm trying to draw my model (exported from milkshape - that has many shared vertices) with the gldrawelements function. i understand milkshape is short changing me on vertex, normal and uv data (because of shared vertices). i also understand i need to make an array for gldrawelements made up of;

verx very verz
norx nory norz (this vertex normal)
u v (this vertex uv)

this is where i get a little frazzled. i know gldrawelements uses _one_ index (the triangles list) to draw the three vertex, normal and uv data arrays. what i cant wrap my head around is, when i unshare a vertex, where does this new vertex go in the new vertex array? after the vertex in question? at the end? what im super unclear on is what happens with the ordering of the triangles? do i make a new triangle? or do i just update the triangle? does the number of triangles stay the same? im so confused! :(

i wrote a few test programs to duplicate data on what i though was the right way and ended up with some silly high numbers of vertices? i've even tried writing a plugin with the milkshape sdk. the entire program seems to run on this shared vertices idea. i cant find a way to get the real vertex count (always the shared vertex count).

anyway, i figure the following with the exported ascii format;

if the vertex exists > check for same uv coords
if same uv coords > disregard?
if not the same uv coords > add vertex, normal, uv and bone data to the end of their new arrays

now what would i do? i surely need todo something with the triangle data? i'd have all these extra vertices and the triangle list wouldnt point to any of them?

the maximum number of vertices would be (number of vertices * 3) right? what about the triangles? does the number of triangles ever increase?

so unsure...

thanks alot for your time!

regards,


justin
Advertisement
When you "unshare" a vertex you are duplicating that vertex. The triangle count doesn't change, but some of the triangles that were referencing the original vertex will now be referencing the new one. Where the new vertex gets stored in the vertex array isn't particularly important, just keep in mind that any vertices that move from one index to another will require having to update the vertex indices of any triangles that refer to them. Adding the new vertex to the end of the array is therefore the easiest since the only faces that have to be updated are those referencing the newly-created vertex.
The easiest way to think about this might be to not think of "amending" your existing data but to just start from scratch and build a new set of arrays (provided you are not trying to do this in real time!).

What I did when I had this issue was to use a map of 3-tuples to generate my new data. So it was a function that would return a new index from a vertex index + normal index + uv index.

I'm not promising below code is correct (threw it together off top of my head), but maybe will give you the idea.

originalVerts[N][3];originalNormals[N][3];originalUVs[N][2];originalFaces[N][3]; //array of 3-index vertices (vertex,normal,uv)float newVertexData[N][8];int newFaces[N];map vertexmap;for(i=0;i<originalFaces.size();i++){  if(exists(vertexmap(originalfaces[0],originalfaces[1],originalfaces[2])){    newFaces.push_back(vertexmap(originalfaces[0],originalfaces[1],originalfaces[2]);  } else {    float data[8] = {originalVerts[originalfaces[0]], originalNormals[originalfaces[1]], originalUVs[originalfaces[2]])    newVertexData.push_back(data);    vertexmap(originalfaces[0],originalfaces[1],originalfaces[2]) = newVertexData.size()    newFaces.push_back(newVertexData.size())  }}   }
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
hello again,

thanks for your excellent replys 0xffffffff and karwosts! you both helped me simplify things alot (i appear to have overly complicated things on this one?). i've spent the last day thinking about this and still have a few questions. i want to run my new understandings past you if thats ok? i dont quite understand where this uv coord you check against exists? because milkshape stores each uv coord with each vertex?

please correct me on my new understandings if i am wrong;

if a shared vertice appears anywhere in the triangle index list more than once, i need to duplicate that vertice?

each entry in a vertex array made up of (verx, very, verz, norx, nory, norz, u, v) is one vertex?

if a shared vertice gets duplicated, the triangle index that was pointing to that vertice gets updated to the location of that newly duplicated vertice?

...



the milkshape ascii format stores a u/v coord with each vertex. this confuses me. when i duplicate a vertex, what uv coords am i checking against? i've seen a few examples of vertice duplication and cant work out where this uv coord you check against is coming from?

when i read a milkshape ascii model i would store data somethingl like this;

vertex[numvertices][3]normal[numnormals][3] < less than numverticesuv[numvertices][2] < same as numverticesvertextriangle[numtriangles][3] < this points to the vertex[] arraynormaltriangle[numtriangles][3] < this points to the normal[] array


...

i assume i fill the vertex array like this;

for (verx = 0; verx < nvertices; verx++) { nt = 0; for (trix = 0; trix < ntriangles; trix++) {  for (indx = 0; indx < 3; indx++) {   if (triangles[trix][indx] == verx) {    // this triangle index is pointing to our vertex in question!    nt++;    if (nt == 1) {     // this is the first time we find this vertex in any triangle indexes...     // add this vertex to the new vertex array?    }    else {     // this vertex is being used again...     // do i just duplicate this vertex, add it to the new vertex array and update the triangle list to point to this duplicated vertex?     // i dont need to check for uv coords because milkshape stores each uv with each vertex, therefore it is already a unique coord?    }   }  } }}


...

i feel silly for not understanding this. i have hand drawn pictures and everything! just a few unsure details left...

thanks for your effort, time and your patience! :)

best regards,


justin
I don't know the specifics of the milkshape format, but there are cases where you could have a vertex that has two different UV's.

Consider a cube that has a different texture on each side. You'll still only have 8 vertex positions, but you'd need 6x4 = 24 uv coords. Maybe the milkshape already duplicates these for you and give you 24 vertices, but in the most efficient data packing there can be more or less uv's than vertices.

I don't think I can quickly explain all your questions to you, but you sound like you've got it mostly thought out. I'd suggest that you just grab yourself some easily debuggable meshes (cube, sphere, etc) and start working on your code.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
hey there...

just following up on this; i did as you said karwosts and grabbed a mesh with a texture and kept at it.

im glad to say i finally got it to work :)

just to clarify, milkshape does appear to store unique uv data... as i had suspected?

thankyou 0xffffffff and karwosts for all your help! what a great community ;)

regards,


justin

This topic is closed to new replies.

Advertisement