ashstampede
Programmer
I could really really use some help on making my model loader faster, it is loading .obj file format. There area where it is slow is converting the mesh data to opengl VBO data. so it looks for duplicate vertex,normal and uv data and creates indices as appropriatly.
a model with 570 faces loads in like 2 seconds, but i have a model with 25000+ faces, I waited maybe 20mins with it not showing on the screen, yet i kept hitting a break point and it was still processing.
I am using stl vectors as my containers
I think this is the main problem area, the compare section
and the model sorting in its entirity
a model with 570 faces loads in like 2 seconds, but i have a model with 25000+ faces, I waited maybe 20mins with it not showing on the screen, yet i kept hitting a break point and it was still processing.
I am using stl vectors as my containers
I think this is the main problem area, the compare section
Code:
for(unsigned int h = 0; h < ActualVertexArraySize; h++)//we will already set 0 so move to next element for the IB
{
//because we start from the beginning each time need to ensure we dont count the current data
if(iterVT != endVT)
{
//check the vertices
//use the temp data to compare with the rest of the vertex
if(FLOATCOMPARE(pVT.x,iterVT->x)&&
FLOATCOMPARE(pVT.y,iterVT->y)&&
FLOATCOMPARE(pVT.z,iterVT->z) )
{
if(hasNormal)
{
if(iterNT != endNT)
{
if(FLOATCOMPARE(pNT.x,iterNT->x)&&
FLOATCOMPARE(pNT.y,iterNT->y)&&
FLOATCOMPARE(pNT.z,iterNT->z) )
{
if(hasUV)
{
if(FLOATCOMPARE(pUV.u,iterUV->u)&&
FLOATCOMPARE(pUV.v,iterUV->v) )
{
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}//end compare UV
}
else
{
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}
}//end compare normals
}//check if normal iterator in range
}//end if hasNormal
else if(hasUV)
{
if(iterUV != endUV)
{
if(FLOATCOMPARE(pUV.u,iterUV->u)&&
FLOATCOMPARE(pUV.v,iterUV->v) )
{
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}//end comapre UV
}//check if uv iterator in range
}//end else if hasUV
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}//end vert compare
}
if(iterVT != endVT)
iterVT++;
if(iterNT != endNT && hasNormal)
iterNT++;
if(iterUV != endUV && hasUV)
iterUV++;
}//end for actual vertex size
//the element was unique so add it as a new vertexsize, jump and increment the index buffer.
if(!reuse)
{
currentMesh.triangleIndexBuffer[index]= ActualVertexArraySize++;
vtBuffer.push_back(pVT);
endVT = vtBuffer.end();
if(hasNormal)
{
ntBuffer.push_back(pNT);
endNT = ntBuffer.end();
}
if(hasUV)
{
uvBuffer.push_back(pUV);
endUV = uvBuffer.end();
}
}
//reset the iterators
iterVT = vtBuffer.begin();
iterNT = ntBuffer.begin();
iterUV = uvBuffer.begin();
and the model sorting in its entirity
Code:
for(unsigned int currentFace= 0; currentFace < currentMesh.meshData->numFaces; currentFace++)
{
bool hasNormal =false; bool hasUV = false;
bool reuse = false;
//short hand reference
pf = currentMesh.meshData->faceList[currentFace];
//did we count normals and uv's when reading the mesh data
if(currentMesh.meshData->numNormals > 0)
{
hasNormal = true;
pNT = currentMesh.meshData->normalList[pf.normalIndices[0]];
}
if(currentMesh.meshData->numUV > 0)
hasUV = true;
//check for duplicate vertices,normals and uv
/*Here we use K to represent 3 points of a triangle
We use index to move along the currentFace and reference the actual data of a uv,normal,or vertex*/
for(int k = 0; k < 3; k++, index++)
{
pVT = currentMesh.meshData->vertexList[pf.vertIndices[k]];
if(hasNormal && currentMesh.meshData->numNormals > 1 )
{
pNT = currentMesh.meshData->normalList[pf.normalIndices[k]];
}
if(hasUV)
{
pUV = currentMesh.meshData->uvList[pf.uvIndices[k]];
}
//go through all the list list of normals, UV and vertices to check if they are in the VBO
//assign Indices based on,
for(unsigned int h = 0; h < ActualVertexArraySize; h++)
{
//because we start from the beginning each time need to ensure we dont count the current data
if(iterVT != endVT)
{
//check the vertices
//use the temp data to compare with the rest of the vertex
if(FLOATCOMPARE(pVT.x,iterVT->x)&&
FLOATCOMPARE(pVT.y,iterVT->y)&&
FLOATCOMPARE(pVT.z,iterVT->z) )
{
if(hasNormal)
{
if(iterNT != endNT)
{
if(FLOATCOMPARE(pNT.x,iterNT->x)&&
FLOATCOMPARE(pNT.y,iterNT->y)&&
FLOATCOMPARE(pNT.z,iterNT->z) )
{
if(hasUV)
{
if(FLOATCOMPARE(pUV.u,iterUV->u)&&
FLOATCOMPARE(pUV.v,iterUV->v) )
{
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}//end compare UV
}
else
{
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}
}//end compare normals
}//check if normal iterator in range
}//end if hasNormal
else if(hasUV)
{
if(iterUV != endUV)
{
if(FLOATCOMPARE(pUV.u,iterUV->u)&&
FLOATCOMPARE(pUV.v,iterUV->v) )
{
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}//end comapre UV
}//check if uv iterator in range
}//end else if hasUV
//it is a old index, so reuse it, then increment the new index place
currentMesh.triangleIndexBuffer[index]= h;
reuse = true;
break;
}//end vert compare
}
if(iterVT != endVT)
iterVT++;
if(iterNT != endNT && hasNormal)
iterNT++;
if(iterUV != endUV && hasUV)
iterUV++;
}//end for actual vertex size
//the element was unique so add it as a new vertexsize, jump and increment the index buffer.
if(!reuse)
{
currentMesh.triangleIndexBuffer[index]= ActualVertexArraySize++;
vtBuffer.push_back(pVT);
if(hasNormal)
{
ntBuffer.push_back(pNT);
}
if(hasUV)
{
uvBuffer.push_back(pUV);
}
}
//reset the iterators
iterVT = vtBuffer.begin();
iterNT = ntBuffer.begin();
iterUV = uvBuffer.begin();
endVT = vtBuffer.end();
endNT = ntBuffer.end();
endUV = uvBuffer.end();
reuse = false;
}//end loop per trangle
if(currentIterVT != currentMesh.meshData->vertexList.end())
currentIterVT++;
if(currentIterUV != currentMesh.meshData->uvList.end() && hasUV)
currentIterUV++;
if(currentIterNT != currentMesh.meshData->normalList.end() && hasNormal)
currentIterNT++;
}//for current face