I'm having some trouble creating a custom mesh loader. I'm using version 1.8.1.
I need to confirm the following:
1) Can I specify indices as triangle as well Quad or arbitrary polygon indices in the same indices list inside SMeshBuffer?
The problem I have in loading a mesh is that it has different polygon faces. 3, 4 or n vertices sides polygons.
If I create triangle indices then I have no idea how to automate the clockwise winding.
The structure of the mesh is attached below.
2) Or The indices must represent triangles? such that number of indices = number of triangles*3?
3) Third question. Is there function to automatically fix the winding?
Thanks guys
Code: Select all
ifstream iFile(filename);
std::string line;
std::vector<std::vector<std::string>> vecValues;
while (getline(iFile, line)) {
/* Printing goes here. */
if (line == "*") break;
}
getline(iFile, line);
std::vector<vector3df> listPos;
int posCount = std::stoi(line);
for (int i = 0; i < posCount; ++i)
{
getline(iFile, line);
std::vector<std::string> out = split(line, ' ');
listPos.push_back(vector3df(std::stof(out[0]), std::stof(out[1]), std::stof(out[2])));
}
getline(iFile, line); //A zero here.
getline(iFile, line);
std::vector<std::vector< int>> listLinePair;
int lineListPairCount = std::stoi(line);
for (int i = 0; i < lineListPairCount; ++i)
{
getline(iFile, line);
std::vector<std::string> out = split(line, ' ');
std::vector<int> vals;
for (int j = 0; j < out.size(); ++j)
{
vals.push_back(std::stoi(out[j]));
}
listLinePair.push_back(vals);
}
std::vector<std::vector<int>> lisFacesIndexes; //Positive and -ve are the directions of the line joins
getline(iFile, line);
int linefaceCount = std::stoi(line);
for (int i = 0; i < linefaceCount; ++i)
{
getline(iFile, line);
std::vector<std::string> out = split(line, ' ');
std::vector<int> vals;
for (int j = 0; j < out.size(); ++j)
{
vals.push_back(std::stoi(out[j]));
}
lisFacesIndexes.push_back(vals);
}
/* While there is still a line. */
while (getline(iFile, line)) {
/* Printing goes here. */
}
iFile.close();
irr::scene::SMesh* Mesh = new irr::scene::SMesh();
SMeshBuffer *buf = 0;
buf = new SMeshBuffer();
Mesh->addMeshBuffer(buf);
buf->drop();
buf->Vertices.reallocate(posCount);
buf->Vertices.set_used(posCount);
float scaleFactor = 0.01;
for (int i = 0; i < posCount; ++i)
{
vector3df p = scaleFactor*listPos[i];
buf->Vertices[i] = video::S3DVertex(p.X, p.Z, p.Y, 1, 1, 1,
video::SColor(255, 255, 255, 255),1, 1);
}
//Perform adding indices here.
for (int i = 0; i < linefaceCount; ++i)
{
int faceIndexesCount = lisFacesIndexes[i].size();
std::vector<int> vecFaceIndex = lisFacesIndexes[i];
int previousIndex = -1;
int beginIndex = -1;
int verticeCount = 0;
int totalVertice = 0;
std::vector< vector<int>> lstTriIndexes;
std::vector<int> vec;
for (int j = faceIndexesCount - 1; j >= 1; --j)
{
int pairValJ = abs(vecFaceIndex[j]) - 1;
std::vector<int> lstIndexes = listLinePair[pairValJ];
if (vecFaceIndex[j] > 0)
{
for (int k = lstIndexes.size() - 1; k >= 0; --k)
{
int index = lstIndexes[k];
if (previousIndex != index)
{
System::Diagnostics::Debug::WriteLine(index.ToString());
totalVertice++;
verticeCount++;
vec.push_back(index);
previousIndex = index;
}
if (verticeCount == 3) //Triangle created. Make new one
{
lstTriIndexes.push_back(vec);
vec = vector < int >() ;
verticeCount = 0;
previousIndex = -1;
}
}
}
else
{
for (int k = 0; k < lstIndexes.size(); ++k) //Winding back anti clockwise
{
int index = lstIndexes[k];
if (previousIndex != index)
{
totalVertice++;
verticeCount++;
vec.push_back(index);
previousIndex = index;
}
if (verticeCount == 3) //Triangle created. Make new one
{
lstTriIndexes.push_back(vec);
vec = vector < int >();
verticeCount = 0;
previousIndex = -1;
}
}
}
}
for (int j = 0; j < lstTriIndexes.size(); ++j)
{
vector<int> v = lstTriIndexes[j];
if (j < lstTriIndexes.size() - 1)
{
for (int k = 0; k < v.size(); ++k)
{
buf->Indices.push_back(v[k]);
}
}
else
{
buf->Indices.push_back(v[2]);
buf->Indices.push_back(v[0]);
buf->Indices.push_back(v[1]);
}
}
}
buf->recalculateBoundingBox();
Mesh->recalculateBoundingBox();
IMeshSceneNode* myNode = smgr->addMeshSceneNode(Mesh);
smgr->getMeshManipulator()->recalculateNormals(myNode->getMesh(), true, true);
smgr->getMeshManipulator()->recalculateTangents(myNode->getMesh(), false, false,false);
myNode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, true);
myNode->setMaterialFlag(video::EMF_LIGHTING, true);
myNode->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
myNode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
myNode->setDebugDataVisible(E_DEBUG_SCENE_TYPE::EDS_NORMALS);
myNode->setMaterialTexture(0, smgr->getVideoDriver()->getTexture("media/wall.bmp"));
Simple mesh...
Code: Select all
8 //No of vertices
6000.000000 -750.000000 300.000000
6000.000000 750.000000 300.000000
0.000000 750.000000 300.000000
0.000000 -750.000000 300.000000
0.000000 750.000000 0.000000
6000.000000 750.000000 0.000000
6000.000000 -750.000000 0.000000
0.000000 -750.000000 0.000000
0 //Not in used
12 //No of lines joining between two vertices
6 7
5 6
4 5
7 4
3 0
0 1
1 2
2 3
7 3
2 4
1 5
0 6
6 //Number of faces.
//nlines lineid1 lineId2...lineIDnLines
4 4 3 2 1
4 5 6 7 8
4 -4 9 -8 10
4 -3 -10 -7 11
4 -2 -11 -6 12
4 -1 -12 -5 -9
Code: Select all
4 -283 -312 -234 -278
4 -192 -15 -175 313
4 -198 -313 -179 -300
4 -279 314 -194 -287
4 -118 -23 -199 -314
5 315 316 317 318 319
5 320 321 322 323 -101
5 -99 324 -306 -309 -111
9 325 -42 -294 -297 -296 -291 -292 -45 -18
4 -212 326 -280 -109
4 -308 -326 327 -112
3 328 329 330
4 331 332 333 334
5 335 336 337 338 339
3 340 341 342
4 -240 -135 -267 343
4 -299 -261 -288 -196
5 344 345 346 347 348
3 349 350 351
6 352 353 354 355 356 357
4 358 -3 359 -47
4 360 -4 -358 -48
4 -360 -49 361 -1
0
0