   MS3D Trianglebased mesh to VBO arrays
  I'm struggeling a bit with converting my mesh-loaded object into VBO supported arrays.The mesh is of ms3d (milkshape) format, and the structure looks something like this:<Group>triangle_indicesmaterial</Group><Triangle>vertex_indicesvertex_normalstexture_coord_stnormal_coord_xyz</Triangle><Vertex>vertex_coord_xyz</Vertex>For now I only look at solving for 1 group.So, I have arrays set up for my VBO (indices, vertices, normals, texCoords)Filling the vertex array is pretty much straight forward. For vertices I can do:for(int i = 0; i < model->GetNumVertices(); i++){vertices.push_back(model->GetVertex(i)->vertex[0]);vertices.push_back(model->GetVertex(i)->vertex[1]);vertices.push_back(model->GetVertex(i)->vertex[2]);}but then things get a bit complicated. Filling the indices would consist of something likefor each tri_index in model->getGroup()->getTriIndices() do  triangle = model->getTriangle(tri_index);  for each index in triangle->getVertexIndices() do    indices.push_back(index);  end  ...I could probably also extract each vertex normal like I do the indices. But how about the texture coords? Since each triangle has a shared tex-coord, this means that for each vertex that is shared between 4 triangles, it "should" have 4 texture coords? I'm not quite seeing the solution to how to convert that into a flat texCoord array for use in the VBO. Is there a common way to treat this kind of triangle structures when it comes to VBOs?Thanks for any help and insight on the matter![Edited by - Trefall on April 28, 2010 4:20:57 AM]
  Here's the ms3d model loader structure:msModel.hand here's a first attempt that fails misserably:for(int i = 0; i < model->GetNumVertices(); i++){vertices.push_back(model->GetVertex(i)->vertex[0]);vertices.push_back(model->GetVertex(i)->vertex[1]);vertices.push_back(model->GetVertex(i)->vertex[2]);colors.push_back(model->GetVertex(i)->renderColor[0]+0.4f);colors.push_back(model->GetVertex(i)->renderColor[1]+0.4f);colors.push_back(model->GetVertex(i)->renderColor[2]+0.4f);colors.push_back(1.0f);normals.push_back(0.0f);normals.push_back(0.0f);normals.push_back(0.0f);texCoords.push_back(0.0f);texCoords.push_back(0.0f);}for(int i = 0; i < model->GetNumGroups(); i++){for(unsigned int j = 0; j < model->GetGroup(i)->triangleIndices.size(); j++){unsigned short indX = model->GetTriangle(j)->vertexIndices[0];unsigned short indY = model->GetTriangle(j)->vertexIndices[1];unsigned short indZ = model->GetTriangle(j)->vertexIndices[2];indices.push_back(indX);indices.push_back(indY);indices.push_back(indZ);normals[indX+0] = model->GetTriangle(j)->vertexNormals[0][0];normals[indX+1] = model->GetTriangle(j)->vertexNormals[0][1];normals[indX+2] = model->GetTriangle(j)->vertexNormals[0][2];normals[indY+0] = model->GetTriangle(j)->vertexNormals[1][0];normals[indY+1] = model->GetTriangle(j)->vertexNormals[1][1];normals[indY+2] = model->GetTriangle(j)->vertexNormals[1][2];normals[indZ+0] = model->GetTriangle(j)->vertexNormals[2][0];normals[indZ+1] = model->GetTriangle(j)->vertexNormals[2][1];normals[indZ+2] = model->GetTriangle(j)->vertexNormals[2][2];texCoords[indX+0] = model->GetTriangle(j)->s[0];texCoords[indX+1] = model->GetTriangle(j)->t[0];texCoords[indY+0] = model->GetTriangle(j)->s[1];texCoords[indY+1] = model->GetTriangle(j)->t[1];texCoords[indZ+0] = model->GetTriangle(j)->s[2];texCoords[indZ+1] = model->GetTriangle(j)->t[2];}};  Probably it has to do with the smoothing groups in Milkshape. Smoothed vertices also share the same texcoord/normal. Maybe not the easiest way, but you could rebuild the mesh and do the smoothing/optimization yourself, creating suitable array's for VBO's. At least, that's what I'm doing. Maybe not fast, but you could store the mesh in your own format afterwards so you only have to do this once.Load the model as usual. The MS3D format holds triangles where each triangle has it's own 3 normals and texture coordinates. Only the positions are possibly shared amongst multiple triangles. TMS3D_Triangle  = packed recordflag   : word;// selected / hidden infoindices: array[0..2] of word;normal : array[0..2] of TVector3f;{ UV }s : array[0..2] of single;t : array[0..2] of single;SmoothingGroup  : byte;IndexGroup : byte; end; // TMS3D_TriangleInstead of indices, store 3 vertex coordinates as well here for now.Next step is to rebuild the mesh and do the smoothing yourself, given a threshold parameter. Create empty output array's for the positions, normals, texcoords and possibly weights in case you're planning animations as well.For each triangle vertex, find the matching vertices:- positions are the same- texture coordinates are the same- normals (almost) the same: dot( referenceNormal, otherVertex.normal ) > smooth_threshold_parameterIf the match fails, skip the vertex. Later on it will get it's own index. Otherwise if it matches, add the normal and count the samples. Also mark the vertex so you can't use it again for another vertex. When you looped through the entire thing, calculate the average normal and add the results to the output array's. And add the output-array index to an indices array.Repeat the process until all vertices were marked. Finally you will have array's suitable for VBO's with optimized data.Greetings,Rick   ;  Thanks spek for your insight. I'll dig into this some more! Sounds like I'm not the only one who has come over this little headache:linkySo basicaly what you say is that if I want smoothing-groups I have to go over the mesh and perform the conversion like you do... I'm having problems just converting it to a flat array without smoothing though :/ hrm, maybe I just have to stop for a second and think.   ;Quote:Original post by TrefallI could probably also extract each vertex normal like I do the indices. But how about the texture coords? Since each triangle has a shared tex-coord, this means that for each vertex that is shared between 4 triangles, it "should" have 4 texture coords? I'm not quite seeing the solution to how to convert that into a flat texCoord array for use in the VBO. Is there a common way to treat this kind of triangle structures when it comes to VBOs?Thanks for any help and insight on the matter!I recently had to deal with this problem. The way I solved it for every new triangle in the file, I first search through the list of triangles that have already been seen. If the new triangle we're trying to add has a different texture coordinate from any of it's shared vertices, then I create a new vertex. If you want to see some code, it's here:http://github.com/stephenlombardi/slib/blob/master/examples/ms3dview/MS3DToMesh.cppIn my code, each function of that class is a callback. Vertex( .. ) gets called for each vertex, Triangle( .. ) for each triangle, etc.,. You can see in the Triangle method that there is a boolean variable which is set to true if a conflicting texture coordinate is found. When this happened a new vertex is created.   