#include "Object.h" #include <iostream> ///////////////////////////////////////////////////////////////////////// // public constructor/destructor Object::Object(const char* path) { // open file fsMesh.open(path, std::ios::in | std::ios::binary); if (!fsMesh.is_open()) throw std::invalid_argument(std::string("file not found: ") += path); // jump into msh2 todo: search for MSH2 if there is a shadowvolume fsMesh.seekg(8); char tempChunkName[5] = { 0 }; fsMesh.read(reinterpret_cast<char*>(&tempChunkName[0]), sizeof(tempChunkName) - 1); if (strcmp(tempChunkName, "MSH2")) throw std::invalid_argument(std::string("corrupted file MSH2 expected instead of ") += tempChunkName); std::uint32_t tempSize; fsMesh.read(reinterpret_cast<char*>(&tempSize), sizeof(tempSize)); // get all sub chunks from MSH2 loadChunks(lChunkMsh2, fsMesh.tellg(), tempSize); // search for all MODL Chunks for (std::list<chunkHeader*>::iterator it = lChunkMsh2.begin(); it != lChunkMsh2.end(); it++) { if (!strcmp("MODL", (*it)->name)) { modl* tempModl = new modl; tempModl->size = (*it)->size; tempModl->position = (*it)->position; std::list<chunkHeader*> tempChunks; loadChunks(tempChunks, (*it)->position, (*it)->size); // evaluate MODL subchunks for (std::list<chunkHeader*>::iterator it = tempChunks.begin(); it != tempChunks.end(); it++) { if (!strcmp("MTYP", (*it)->name)) { fsMesh.seekg((*it)->position); std::uint32_t tempType; fsMesh.read(reinterpret_cast<char*>(&tempType), sizeof(tempType)); tempModl->type = (mtyp)tempType; } if (!strcmp("MNDX", (*it)->name)) { fsMesh.seekg((*it)->position); fsMesh.read(reinterpret_cast<char*>(&tempModl->zeroBaseIndex), sizeof(tempModl->zeroBaseIndex)); } if (!strcmp("PRNT", (*it)->name)) { fsMesh.seekg((*it)->position); char tempName[33] = { 0 }; fsMesh.read(reinterpret_cast<char*>(&tempName[0]), (*it)->size > 32 ? 32 : (*it)->size); tempModl->parent = tempName; } if (!strcmp("NAME", (*it)->name)) { fsMesh.seekg((*it)->position); char tempName[33] = { 0 }; fsMesh.read(reinterpret_cast<char*>(&tempName[0]), (*it)->size > 32 ? 32 : (*it)->size); tempModl->name = tempName; } if (!strcmp("FLGS", (*it)->name)) { fsMesh.seekg((*it)->position); fsMesh.read(reinterpret_cast<char*>(&tempModl->renderFlags), sizeof(tempModl->renderFlags)); } if (!strcmp("TRAN", (*it)->name)) { fsMesh.seekg((*it)->position); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.scale[0]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.scale[1]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.scale[2]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.rotation[0]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.rotation[1]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.rotation[2]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.rotation[3]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.translation[0]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.translation[1]), sizeof(float)); fsMesh.read(reinterpret_cast<char*>(&tempModl->tran.translation[2]), sizeof(float)); } if (!strcmp("GEOM", (*it)->name)) { } if (!strcmp("SWCI", (*it)->name)) { fsMesh.seekg((*it)->position); fsMesh.read(reinterpret_cast<char*>(&tempModl->swci.type), sizeof(tempModl->swci.type)); fsMesh.read(reinterpret_cast<char*>(&tempModl->swci.data1), sizeof(tempModl->swci.data1)); fsMesh.read(reinterpret_cast<char*>(&tempModl->swci.data2), sizeof(tempModl->swci.data2)); fsMesh.read(reinterpret_cast<char*>(&tempModl->swci.data3), sizeof(tempModl->swci.data3)); } } lModls.push_back(tempModl); //clean up while (!tempChunks.empty()) { chunkHeader* tempCursor = tempChunks.front(); tempChunks.pop_front(); delete tempCursor; } } } // close file fsMesh.close(); } Object::~Object() { //delete Chunk list; } ///////////////////////////////////////////////////////////////////////// // private functions void Object::loadChunks(std::list<chunkHeader*>& destination, std::streampos start, const std::uint32_t end) { // jump to first chunk fsMesh.seekg(start); do { chunkHeader* tempHeader = new chunkHeader(); fsMesh.read(reinterpret_cast<char*>(&tempHeader->name[0]), sizeof(tempHeader->name) - 1); fsMesh.read(reinterpret_cast<char*>(&tempHeader->size), sizeof(tempHeader->size)); tempHeader->position = fsMesh.tellg(); destination.push_back(tempHeader); fsMesh.seekg(tempHeader->size, std::ios_base::cur); // reached end if (fsMesh.tellg() - start == end) break; // error. Maybe the size information is corrupted if (!fsMesh.good()) { std::cout << "WARNING: corrupted file. Trying to continue" << std::endl; fsMesh.clear(); break; } } while (true); std::cout << "got all chunks, totaly found: " << destination.size() << std::endl; } ///////////////////////////////////////////////////////////////////////// // public getter ///////////////////////////////////////////////////////////////////////// // public functions