diff --git a/QtMeshViewer/Header/FileInterface.h b/QtMeshViewer/Header/FileInterface.h index e3b1995..6db9b5c 100644 --- a/QtMeshViewer/Header/FileInterface.h +++ b/QtMeshViewer/Header/FileInterface.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include #include @@ -21,17 +21,17 @@ struct VertexData }; struct Segment { - std::uint32_t textureIndex = 0; + quint32 textureIndex = 0; QVector vertices; QVector indices; }; struct Model { - std::string name = ""; - std::string parent = ""; + QString name = ""; + QString parent = ""; QMatrix4x4 m4x4Translation; QQuaternion quadRotation; - std::vector segmList; + QVector segmList; }; struct Material { @@ -48,8 +48,8 @@ struct Material { float shininess = 80; bool flags[8] = { false }; bool transparent = false; - std::uint8_t rendertype = 0; - std::uint8_t dataValues[2] = { 0 }; + quint8 rendertype = 0; + quint8 dataValues[2] = { 0 }; }; class FileInterface @@ -61,9 +61,9 @@ public: , m_materials(new QVector) { //open file - m_file.open(path.toStdString().c_str(), std::ios::in | std::ios::binary); + m_file.setFileName(path); - if (!m_file.is_open()) + if (!m_file.open(QIODevice::ReadOnly)) throw std::invalid_argument(std::string("ERROR: file not found: ") += path.toStdString()); m_filepath = path.left(path.lastIndexOf(QRegExp("/|\\\\"))); @@ -94,7 +94,7 @@ public: protected: QVector* m_models; - std::fstream m_file; + QFile m_file; QVector* m_materials; BoundingBox m_sceneBbox; QString m_filepath; diff --git a/QtMeshViewer/Header/MshFile.h b/QtMeshViewer/Header/MshFile.h index f5c3fed..9e45284 100644 --- a/QtMeshViewer/Header/MshFile.h +++ b/QtMeshViewer/Header/MshFile.h @@ -1,11 +1,11 @@ #pragma once #include "..\Header\FileInterface.h" - +#include struct ChunkHeader { - char name[5]; - std::uint32_t size; - std::streampos position; + QString name; + quint32 size; + qint64 position; }; enum ModelTyp { @@ -29,22 +29,22 @@ private: virtual void import() Q_DECL_OVERRIDE Q_DECL_FINAL; - void loadChunks(std::list &destination, std::streampos start, const std::uint32_t length); + void loadChunks(QList &destination, qint64 start, const quint32 length); - void analyseMsh2Chunks(std::list &chunkList); + void analyseMsh2Chunks(QList &chunkList); - void analyseMatdChunks(std::list &chunkList); + void analyseMatdChunks(QList &chunkList); - void analyseModlChunks(Model* dataDestination, std::list &chunkList); - void analyseGeomChunks(Model* dataDestination, std::list &chunkList); - void analyseSegmChunks(Model* dataDestination, std::list &chunkList); - void analyseClthChunks(Model* dataDestination, std::list &chunkList); + void analyseModlChunks(Model* dataDestination, QList &chunkList); + void analyseGeomChunks(Model* dataDestination, QList &chunkList); + void analyseSegmChunks(Model* dataDestination, QList &chunkList); + void analyseClthChunks(Model* dataDestination, QList &chunkList); - void readVertex(Segment* dataDestination, std::streampos position); - void readUV(Segment* dataDestination, std::streampos position); + void readVertex(Segment* dataDestination, qint64 position); + void readUV(Segment* dataDestination, qint64 position); void loadTexture(QOpenGLTexture*& destination, QString filepath, QString& filename); - QMatrix4x4 getParentMatrix(std::string parent) const; - QQuaternion getParentRotation(std::string parent) const; + QMatrix4x4 getParentMatrix(QString parent) const; + QQuaternion getParentRotation(QString parent) const; }; \ No newline at end of file diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp index 331eaae..902f3a5 100644 --- a/QtMeshViewer/Source/GeometryEngine.cpp +++ b/QtMeshViewer/Source/GeometryEngine.cpp @@ -5,6 +5,7 @@ #include "..\Header\OutputDevice.h" #include +#include "..\Header\Profiler.h" ///////////////////////////////////////////////////////////////////////// // constructor/destructor @@ -140,6 +141,7 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) void GeometryEngine::loadFile(QString filePath) { + TIC("Start"); // cleanup old stuff and recreate buffers clearData(); m_arrayBuf.create(); @@ -214,5 +216,7 @@ void GeometryEngine::loadFile(QString filePath) clearData(); OutputDevice::getInstance()->print(QString(e.what()), 2); } + + TOC("End"); } diff --git a/QtMeshViewer/Source/MshFile.cpp b/QtMeshViewer/Source/MshFile.cpp index 0e063e8..7cea3ca 100644 --- a/QtMeshViewer/Source/MshFile.cpp +++ b/QtMeshViewer/Source/MshFile.cpp @@ -1,7 +1,6 @@ #include "..\Header\MshFile.h" #include "..\Header\tga.h" #include "..\Header\OutputDevice.h" -#include // helper function to save data from file to any variable type @@ -28,22 +27,22 @@ MshFile::~MshFile() void MshFile::import() { // go to file size information - m_file.seekg(4); + m_file.seek(4); - std::uint32_t tmp_fileSize; - std::list tmp_mainChunks; + quint32 tmp_fileSize; + QList tmp_mainChunks; // get all chunks under HEDR m_file.read(F2V(tmp_fileSize), sizeof(tmp_fileSize)); - loadChunks(tmp_mainChunks, m_file.tellg(), tmp_fileSize); + loadChunks(tmp_mainChunks, m_file.pos(), tmp_fileSize); // evaulate HEDR subchunks (= find MSH2) for (ChunkHeader* it : tmp_mainChunks) { - if (!strcmp("MSH2", it->name)) + if ("MSH2" == it->name) { // get all subchunks - std::list tmp_msh2Chunks; + QList tmp_msh2Chunks; loadChunks(tmp_msh2Chunks, it->position, it->size); // evaluate MSH2 subchunks @@ -68,54 +67,62 @@ void MshFile::import() } } -void MshFile::loadChunks(std::list& destination, std::streampos start, const std::uint32_t length) +void MshFile::loadChunks(QList& destination, qint64 start, const quint32 length) { // jump to first chunk - m_file.seekg(start); + m_file.seek(start); do { ChunkHeader* tmp_header = new ChunkHeader(); + char workaround[5] = { 0 }; // get information - m_file.read(F2V(tmp_header->name[0]), sizeof(tmp_header->name) - 1); + m_file.read(F2V(workaround[0]), sizeof(workaround) -1); + tmp_header->name = QString(workaround); m_file.read(F2V(tmp_header->size), sizeof(tmp_header->size)); - tmp_header->position = m_file.tellg(); + tmp_header->position = m_file.pos(); // store information destination.push_back(tmp_header); // jump to next header - m_file.seekg(tmp_header->size, std::ios_base::cur); - - // out of file. Maybe a size information is corrupted - if (!m_file.good()) + if (!m_file.seek(tmp_header->size + m_file.pos())) { OutputDevice::getInstance()->print("WARNING: corrupted file. Trying to continue..", 1); - m_file.clear(); + m_file.unsetError(); + m_file.seek(0); break; } - } while (m_file.tellg() - start != length); + // out of file. Maybe a size information is corrupted + if (m_file.error() != QFileDevice::NoError) + { + OutputDevice::getInstance()->print("WARNING: corrupted file. Trying to continue..", 1); + m_file.unsetError(); + m_file.seek(0); + break; + } + } while (m_file.pos() - start != length); } -void MshFile::analyseMsh2Chunks(std::list& chunkList) +void MshFile::analyseMsh2Chunks(QList& chunkList) { for (auto& it : chunkList) { // scene information - if (!strcmp("SINF", it->name)) + if ("SINF" == it->name) { // get SINF subchunks - std::list tmp_sinfChunks; + QList tmp_sinfChunks; loadChunks(tmp_sinfChunks, it->position, it->size); // evaluate SINF subchunks for (auto& it : tmp_sinfChunks) { - if (!strcmp("BBOX", it->name)) + if ("BBOX" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); // read in the quaternion float tmp_quat[4]; @@ -143,24 +150,25 @@ void MshFile::analyseMsh2Chunks(std::list& chunkList) } // material list - else if (!strcmp("MATL", it->name)) + else if ("MATL" == it->name) { + OutputDevice::getInstance()->print("loading materials..", 0); // "useless" information how many MATD follow, jump over it - m_file.seekg(it->position); - m_file.seekg(sizeof(std::uint32_t), std::ios_base::cur); + m_file.seek(it->position); + m_file.seek(sizeof(quint32) + m_file.pos()); // get all MATL subchunk - std::list tmp_matlChunks; - loadChunks(tmp_matlChunks, m_file.tellg(), it->size - 4); + QList tmp_matlChunks; + loadChunks(tmp_matlChunks, m_file.pos(), it->size - 4); // evaluate MATL subchunks for (auto& it : tmp_matlChunks) { // This shouldn't be anything else than MATD - if (!strcmp("MATD", it->name)) + if ("MATD" == it->name) { // get all subchunks from MATD - std::list tmp_matdChunks; + QList tmp_matdChunks; loadChunks(tmp_matdChunks, it->position, it->size); m_materials->push_back(Material()); @@ -188,14 +196,15 @@ void MshFile::analyseMsh2Chunks(std::list& chunkList) } // model - else if (!strcmp("MODL", it->name)) + else if ("MODL" == it->name) { + OutputDevice::getInstance()->print("loading model..", 0); Model* new_model = new Model; m_currentType = ModelTyp::null; m_currentRenderFlag = -1; // get all MODL subchunks - std::list tmp_chunks; + QList tmp_chunks; loadChunks(tmp_chunks, it->position, it->size); // evaluate MODL subchunks @@ -215,14 +224,14 @@ void MshFile::analyseMsh2Chunks(std::list& chunkList) } } -void MshFile::analyseMatdChunks(std::list& chunkList) +void MshFile::analyseMatdChunks(QList& chunkList) { for (auto& it : chunkList) { // name - if (!strcmp("NAME", it->name)) + if ("NAME" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -231,9 +240,9 @@ void MshFile::analyseMatdChunks(std::list& chunkList) } // data - else if(!strcmp("DATA", it->name)) + else if("DATA" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); // diffuse for (unsigned int i = 0; i < 4; i++) @@ -252,18 +261,18 @@ void MshFile::analyseMatdChunks(std::list& chunkList) } // attributes - else if (!strcmp("ATRB", it->name)) + else if ("ATRB" == it->name) { // get pointer to current material Material* curMat = &m_materials->back(); // read the attributes - m_file.seekg(it->position); - std::uint8_t flag; + m_file.seek(it->position); + quint8 flag; m_file.read(F2V(flag), sizeof(flag)); - m_file.read(F2V(curMat->rendertype), sizeof(std::uint8_t)); - m_file.read(F2V(curMat->dataValues[0]), sizeof(std::uint8_t)); - m_file.read(F2V(curMat->dataValues[1]), sizeof(std::uint8_t)); + m_file.read(F2V(curMat->rendertype), sizeof(quint8)); + m_file.read(F2V(curMat->dataValues[0]), sizeof(quint8)); + m_file.read(F2V(curMat->dataValues[1]), sizeof(quint8)); // flags // 0: emissive @@ -276,16 +285,16 @@ void MshFile::analyseMatdChunks(std::list& chunkList) // 7: specular for (unsigned int i = 0; i < 8; i++) - curMat->flags[i] = (std::uint8_t)(flag << (7 - i)) >> 7; + curMat->flags[i] = (quint8)(flag << (7 - i)) >> 7; curMat->transparent = curMat->flags[2] || curMat->flags[3] || curMat->flags[4] || curMat->flags[6] || curMat->rendertype == 4; } // texture 0 - else if (!strcmp("TX0D", it->name)) + else if ("TX0D" == it->name) { // get the texture name - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -298,10 +307,10 @@ void MshFile::analyseMatdChunks(std::list& chunkList) } // texture 1 - else if (!strcmp("TX1D", it->name)) + else if ("TX1D" == it->name) { // get the texture name - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -313,10 +322,10 @@ void MshFile::analyseMatdChunks(std::list& chunkList) } // texture 2 - else if (!strcmp("TX2D", it->name)) + else if ("TX2D" == it->name) { // get the texture name - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -325,10 +334,10 @@ void MshFile::analyseMatdChunks(std::list& chunkList) } // texture 3 - else if (!strcmp("TX3D", it->name)) + else if ("TX3D" == it->name) { // get the texture name - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -338,23 +347,23 @@ void MshFile::analyseMatdChunks(std::list& chunkList) } } -void MshFile::analyseModlChunks(Model * dataDestination, std::list& chunkList) +void MshFile::analyseModlChunks(Model * dataDestination, QList& chunkList) { for (auto& it : chunkList) { // model type - if (!strcmp("MTYP", it->name)) + if ("MTYP" == it->name) { - m_file.seekg(it->position); - std::uint32_t tmp_type; + m_file.seek(it->position); + quint32 tmp_type; m_file.read(F2V(tmp_type), sizeof(tmp_type)); m_currentType = (ModelTyp)tmp_type; } // parent name - else if (!strcmp("PRNT", it->name)) + else if ("PRNT" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -363,9 +372,9 @@ void MshFile::analyseModlChunks(Model * dataDestination, std::list } // model name - else if (!strcmp("NAME", it->name)) + else if ("NAME" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -374,20 +383,20 @@ void MshFile::analyseModlChunks(Model * dataDestination, std::list } // render flags - else if (!strcmp("FLGS", it->name)) + else if ("FLGS" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); m_file.read(F2V(m_currentRenderFlag), sizeof(m_currentRenderFlag)); } // translation - else if (!strcmp("TRAN", it->name)) + else if ("TRAN" == it->name) { float tmp_scale[3]; float tmp_rotation[4]; float tmp_trans[3]; - m_file.seekg(it->position); + m_file.seek(it->position); // read in the data for (int i = 0; i < 3; i++) @@ -410,14 +419,14 @@ void MshFile::analyseModlChunks(Model * dataDestination, std::list } // geometry data - else if (!strcmp("GEOM", it->name)) + else if ("GEOM" == it->name) { // don't get null, bone, shadowMesh and hidden mesh indices if (m_currentType == null || m_currentType == bone || m_currentType == shadowMesh || m_currentRenderFlag == 1) continue; // get all GEOM subchunks - std::list tmp_geomChunks; + QList tmp_geomChunks; loadChunks(tmp_geomChunks, it->position, it->size); // evaluate GEOM subchunks @@ -434,15 +443,15 @@ void MshFile::analyseModlChunks(Model * dataDestination, std::list } } -void MshFile::analyseGeomChunks(Model * dataDestination, std::list& chunkList) +void MshFile::analyseGeomChunks(Model * dataDestination, QList& chunkList) { for (auto& it : chunkList) { // segment - if (!strcmp("SEGM", it->name)) + if ("SEGM" == it->name) { // get all SEGM subchunks - std::list tmp_segmChunks; + QList tmp_segmChunks; loadChunks(tmp_segmChunks, it->position, it->size); // evaluate SEGM subchunks @@ -458,10 +467,10 @@ void MshFile::analyseGeomChunks(Model * dataDestination, std::list } // cloth - else if (!strcmp("CLTH", it->name)) + else if ("CLTH" == it->name) { // get all CLTH subchunks - std::list tmp_clthChunks; + QList tmp_clthChunks; loadChunks(tmp_clthChunks, it->position, it->size); // evaluate CLTH subchunks @@ -478,30 +487,30 @@ void MshFile::analyseGeomChunks(Model * dataDestination, std::list } } -void MshFile::analyseSegmChunks(Model * dataDestination, std::list& chunkList) +void MshFile::analyseSegmChunks(Model * dataDestination, QList& chunkList) { Segment* new_segment = new Segment; for (auto& it : chunkList) { // material index - if (!strcmp("MATI", it->name)) + if ("MATI" == it->name) { - m_file.seekg(it->position); + m_file.seek(it->position); m_file.read(F2V(new_segment->textureIndex), sizeof(new_segment->textureIndex)); } // position list (vertex) - else if (!strcmp("POSL", it->name)) + else if ("POSL" == it->name) { readVertex(new_segment, it->position); } // normals - else if (!strcmp("NRML", it->name)) + else if ("NRML" == it->name) { - std::uint32_t tmp_size; - m_file.seekg(it->position); + quint32 tmp_size; + m_file.seek(it->position); m_file.read(F2V(tmp_size), sizeof(tmp_size)); if (tmp_size < (unsigned) new_segment->vertices.size()) @@ -525,18 +534,18 @@ void MshFile::analyseSegmChunks(Model * dataDestination, std::list } // uv - else if (!strcmp("UV0L", it->name)) + else if ("UV0L" == it->name) { readUV(new_segment, it->position); } // polygons (indices into vertex/uv list) - else if (!strcmp("STRP", it->name)) + else if ("STRP" == it->name) { // jump to the data section and read the size; - std::uint32_t tmp_size; - m_file.seekg(it->position); + quint32 tmp_size; + m_file.seek(it->position); m_file.read(F2V(tmp_size), sizeof(tmp_size)); int highBitCount(0); @@ -545,7 +554,7 @@ void MshFile::analyseSegmChunks(Model * dataDestination, std::list for (unsigned int i = 0; i < tmp_size; i++) { // ReadData - std::uint16_t tmp_value; + quint16 tmp_value; m_file.read(F2V(tmp_value), sizeof(tmp_value)); // Check if highbit is set @@ -553,7 +562,7 @@ void MshFile::analyseSegmChunks(Model * dataDestination, std::list { highBitCount++; // remove the high bit, to get the actually value - tmp_value = (std::uint16_t(tmp_value << 1) >> 1); + tmp_value = (quint16(tmp_value << 1) >> 1); } // save data @@ -607,17 +616,17 @@ void MshFile::analyseSegmChunks(Model * dataDestination, std::list dataDestination->segmList.push_back(new_segment); } -void MshFile::analyseClthChunks(Model * dataDestination, std::list& chunkList) +void MshFile::analyseClthChunks(Model * dataDestination, QList& chunkList) { Segment* new_segment = new Segment; for (auto& it : chunkList) { // texture name - if (!strcmp("CTEX", it->name)) + if ("CTEX" == it->name) { // read the texture name - m_file.seekg(it->position); + m_file.seek(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); @@ -638,30 +647,30 @@ void MshFile::analyseClthChunks(Model * dataDestination, std::list } // position list (vertex) - else if (!strcmp("CPOS", it->name)) + else if ("CPOS" == it->name) { readVertex(new_segment, it->position); } // uv - else if (!strcmp("CUV0", it->name)) + else if ("CUV0" == it->name) { readUV(new_segment, it->position); } // triangles (indices into vertex/uv list) - else if (!strcmp("CMSH", it->name)) + else if ("CMSH" == it->name) { // jump to the data section and read the size; - std::uint32_t tmp_size; - m_file.seekg(it->position); + quint32 tmp_size; + m_file.seek(it->position); m_file.read(F2V(tmp_size), sizeof(tmp_size)); // for every triangle.. for (unsigned int i = 0; i < tmp_size * 3; i++) { - std::uint32_t tmp_value; - m_file.read(F2V(tmp_value), sizeof(std::uint32_t)); + quint32 tmp_value; + m_file.read(F2V(tmp_value), sizeof(quint32)); new_segment->indices.push_back((GLuint)tmp_value); } @@ -671,10 +680,10 @@ void MshFile::analyseClthChunks(Model * dataDestination, std::list dataDestination->segmList.push_back(new_segment); } -void MshFile::readVertex(Segment * dataDestination, std::streampos position) +void MshFile::readVertex(Segment * dataDestination, qint64 position) { - std::uint32_t tmp_size; - m_file.seekg(position); + quint32 tmp_size; + m_file.seek(position); m_file.read(F2V(tmp_size), sizeof(tmp_size)); for (unsigned int i = 0; i < tmp_size; i++) @@ -690,10 +699,10 @@ void MshFile::readVertex(Segment * dataDestination, std::streampos position) } } -void MshFile::readUV(Segment * dataDestination, std::streampos position) +void MshFile::readUV(Segment * dataDestination, qint64 position) { - std::uint32_t tmp_size; - m_file.seekg(position); + quint32 tmp_size; + m_file.seek(position); m_file.read(F2V(tmp_size), sizeof(tmp_size)); if (tmp_size < (unsigned) dataDestination->vertices.size()) @@ -746,13 +755,13 @@ void MshFile::loadTexture(QOpenGLTexture *& destination, QString filepath, QStri destination = new_texture; } -QMatrix4x4 MshFile::getParentMatrix(std::string parent) const +QMatrix4x4 MshFile::getParentMatrix(QString parent) const { QMatrix4x4 matrix; for (auto& it : *m_models) { - if (!strcmp(parent.c_str(), it->name.c_str())) + if (parent == it->name) { matrix = getParentMatrix(it->parent) * it->m4x4Translation; break; @@ -762,13 +771,13 @@ QMatrix4x4 MshFile::getParentMatrix(std::string parent) const return matrix; } -QQuaternion MshFile::getParentRotation(std::string parent) const +QQuaternion MshFile::getParentRotation(QString parent) const { QQuaternion rotation; for (auto& it : *m_models) { - if (!strcmp(parent.c_str(), it->name.c_str())) + if (parent == it->name) { rotation = getParentRotation(it->parent) * it->quadRotation; break;