diff --git a/src/engine/include/models/mesh_frame.hpp b/src/engine/include/models/mesh_frame.hpp index 99ec249..d078bca 100644 --- a/src/engine/include/models/mesh_frame.hpp +++ b/src/engine/include/models/mesh_frame.hpp @@ -119,6 +119,9 @@ public: const u8 &areMaterialsAllocated() const { return _areMaterialsAllocated; }; const u8 &isBoundingBoxCalculated() const { return _isBoundingBoxCalculated; }; + const u8 &areSTsPresent() const { return _areSTsPresent; }; + const u8 &areNormalsPresent() const { return _areNormalsPresent; }; + /** Set STs count and allocate memory. */ void allocateSTs(const u32 &t_val); @@ -131,6 +134,9 @@ public: /** Set materials count and allocate memory. */ void allocateMaterials(const u32 &t_val); + void setSTsPresent(const u8 &b) { _areSTsPresent = b; }; + void setNormalsPresent(const u8 &b) { _areNormalsPresent = b; }; + /** * Calculates bounding box (AABB) for frame and for materiaals. * Should be called by data loader, @@ -144,6 +150,8 @@ private: _areVerticesAllocated, _areNormalsAllocated, _areMaterialsAllocated, + _areSTsPresent, + _areNormalsPresent, _isBoundingBoxCalculated; u32 vertexCount, stsCount, normalsCount, materialsCount; MeshMaterial *materials; diff --git a/src/engine/loaders/obj_loader.cpp b/src/engine/loaders/obj_loader.cpp index a200589..082cd3f 100644 --- a/src/engine/loaders/obj_loader.cpp +++ b/src/engine/loaders/obj_loader.cpp @@ -71,27 +71,112 @@ void ObjLoader::load(MeshFrame *o_result, char *t_filename, float t_scale, u8 t_ } else if (strcmp(lineHeader, "f") == 0) { - int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", - &vertexIndex[0], &coordIndex[0], &normalIndex[0], - &vertexIndex[1], &coordIndex[1], &normalIndex[1], - &vertexIndex[2], &coordIndex[2], &normalIndex[2]); - if (matches != 9) - PRINT_ERR(".obj can't be read by this simple parser. Try exporting with other options"); - else + + int *x; + fpos_t start; + fgetpos(file, &start); + int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", x, x, x, x, x, x, x, x, x); + fsetpos(file, &start); + int newerMatches = 0; + + switch (matches) + { + /** Vs, VTs and VNs all set */ + case 9: + { + fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", + &vertexIndex[0], &coordIndex[0], &normalIndex[0], + &vertexIndex[1], &coordIndex[1], &normalIndex[1], + &vertexIndex[2], &coordIndex[2], &normalIndex[2]); + } + break; + /** Loaded only two digits (V, VT) succesfuly. Not setting VN. */ + case 2: + { + fscanf(file, "%d/%d/ %d/%d/ %d/%d/\n", + &vertexIndex[0], &coordIndex[0], + &vertexIndex[1], &coordIndex[1], + &vertexIndex[2], &coordIndex[2]); + } + break; + /** Only V set. Checking for existance of VT or VN. */ + case 1: + { + /** Check for existance of V/// configuration.. */ + newerMatches = fscanf(file, "%d/// %d/// %d///\n", x, x, x); + fsetpos(file, &start); + if (newerMatches == 3) + { + /** Configuration confirmed. */ + fscanf(file, "%d/// %d/// %d///\n", &vertexIndex[0], &vertexIndex[1], &vertexIndex[2]); + } + else + { + /** Failed, checking configuration V//VN */ + newerMatches = fscanf(file, "%d//%d %d//%d %d//%d", x, x, x, x, x, x); + fsetpos(file, &start); + if (newerMatches == 6) + { + /** Configuration confirmed. */ + newerMatches = fscanf(file, "%d//%d %d//%d %d//%d", + &vertexIndex[0], &normalIndex[0], + &vertexIndex[1], &normalIndex[1], + &vertexIndex[2], &normalIndex[2]); + } + else + { + /**Unknown configuration.*/ + PRINT_ERR("Unknown .obj face for .obj file!"); + } + } + break; + } + default: + PRINT_ERR("Unknown faces format in .obj file!"); + break; + } + + if (matches == 9 || matches == 2 || matches == 1) { o_result->getMaterial(materialsI).setVertexFace(faceI, vertexIndex[0] - 1); o_result->getMaterial(materialsI).setVertexFace(faceI + 1, vertexIndex[1] - 1); o_result->getMaterial(materialsI).setVertexFace(faceI + 2, vertexIndex[2] - 1); - + } + if (matches == 9 || matches == 2) + { o_result->getMaterial(materialsI).setSTFace(faceI, coordIndex[0] - 1); o_result->getMaterial(materialsI).setSTFace(faceI + 1, coordIndex[1] - 1); o_result->getMaterial(materialsI).setSTFace(faceI + 2, coordIndex[2] - 1); + o_result->setSTsPresent(true); + } + if (matches == 9) + { o_result->getMaterial(materialsI).setNormalFace(faceI, normalIndex[0] - 1); o_result->getMaterial(materialsI).setNormalFace(faceI + 1, normalIndex[1] - 1); o_result->getMaterial(materialsI).setNormalFace(faceI + 2, normalIndex[2] - 1); + o_result->setNormalsPresent(true); faceI += 3; } + else if (matches == 2) + { + faceI += 2; + } + else if (matches == 1) + { + if (newerMatches == 3) + { + faceI += 1; + } + else if (newerMatches == 6) + { + o_result->getMaterial(materialsI).setNormalFace(faceI, normalIndex[0] - 1); + o_result->getMaterial(materialsI).setNormalFace(faceI + 1, normalIndex[1] - 1); + o_result->getMaterial(materialsI).setNormalFace(faceI + 2, normalIndex[2] - 1); + o_result->setNormalsPresent(true); + faceI += 2; + } + } } } else diff --git a/src/engine/models/mesh_frame.cpp b/src/engine/models/mesh_frame.cpp index ff9883d..b193577 100644 --- a/src/engine/models/mesh_frame.cpp +++ b/src/engine/models/mesh_frame.cpp @@ -25,6 +25,8 @@ MeshFrame::MeshFrame() _areVerticesAllocated = false; _areNormalsAllocated = false; _areMaterialsAllocated = false; + _areSTsPresent = false; + _areNormalsPresent = false; } MeshFrame::~MeshFrame()