--- Irrlicht.old/CXFileReader.cpp 2005-08-20 21:17:52.000000000 +0200 +++ Irrlicht/CXFileReader.cpp 2005-12-18 14:18:34.000000000 +0100 @@ -7,6 +7,7 @@ #include "fast_atof.h" #include #include +#include namespace irr { @@ -14,7 +15,7 @@ { CXFileReader::CXFileReader(io::IReadFile* file) -: ErrorHappened(false), Buffer(0), Size(0), P(0), End(0) +: ErrorHappened(false), Buffer(0), Size(0), P(0), End(0), binary(false) { if (!file) { @@ -102,9 +103,9 @@ for (i=0; iMeshes[m].NormalIndices[i] < 0) + if (frame->Meshes[m].NormalIndices[i] == 0) { - sprintf(tmp, "XLoader error: normal index %d smaller than 0 in mesh %d: %d, frame '%s'", + sprintf(tmp, "XLoader error: normal index %d equals 0 in mesh %d: %d, frame '%s'", i, m, frame->Meshes[m].NormalIndices[i], frame->Name.c_str()); os::Printer::log(tmp, ELL_ERROR); error = true; @@ -171,23 +172,37 @@ MinorVersion = strtol(tmp, &P, 10); //! read format - if (Buffer[8] != 't' || Buffer[9] != 'x' || - Buffer[10] != 't' || Buffer[11] != ' ') + if (strncmp(&Buffer[8], "txt ", 4) == 0) + { + binary = false; + } + else if (strncmp(&Buffer[8], "bin ", 4) == 0) + { + binary = true; + } + else { os::Printer::log("Only text encoded x files supported currently.", ELL_WARNING); return false; } //! read float size - if (Buffer[12] == '0' || Buffer[13] != '0' || - Buffer[14] != '3' || Buffer[15] != '2') - FloatSize = 32; + if (strncmp(&Buffer[12], "0032", 4) == 0) + FloatSize = 4; // 4 bytes = 32 bits = float + else if (strncmp(&Buffer[12], "0064", 4) == 0) + FloatSize = 8; // 8 bytes = 64 bits = double else - FloatSize = 64; + { + os::Printer::log("Float size not supported.", ELL_WARNING); + return false; + } P = &Buffer[16]; + if (!binary) + { readUntilEndOfLine(); + } return true; } @@ -358,6 +373,28 @@ os::Printer::log("CXFileReader: Reading template"); #endif + if (binary) { + // get the template name + core::stringc name = getNextToken(); + + // check & skip open brace + if (readBinWord() != 10) { + os::Printer::log("Left delimiter in template data object missing.", + name.c_str(), ELL_ERROR); + return false; + } + + // skip all data members + while (true) { + core::stringc s = getNextToken(); + if (s == "}") + break; + if (s.size() == 0) + return false; + } + } + else // text + { // parse a template data object. Currently not stored. core::stringc name = getNextToken(); @@ -382,6 +419,7 @@ if (s.size() == 0) return false; } + } return true; } @@ -399,16 +437,53 @@ return false; } + u16 tok; + u32 count = 0; + // read vertex count + u32 nVertices; + if (binary) + { + nVertices = readBinInt(); + } + else + { findNextNoneWhiteSpaceNumber(); - s32 nVertices = readInt(); + nVertices = readInt(); + } // read vertices mesh.Vertices.set_used(nVertices); - for (s32 n=0; n polygonfaces; s32 currentIndex = 0; - for (s32 k=0; k polygonfaces; + + if (binary) + { + tok = readBinWord(); + if (tok != 6) + { + os::Printer::log("Binary X: MeshNormals: Expect integer list (face normal indices)", ELL_WARNING); + return false; + } + count = readBinDWord(); + readed = 0; + + nFNormals = readBinDWord(); ++readed; + } + else + { findNextNoneWhiteSpaceNumber(); - s32 nFNormals = strtol(P, &P, 10); + nFNormals = strtol(P, &P, 10); + } + normalIndices.set_used(triangulatedIndexCount); - s32 normalidx = 0; - core::array polygonfaces; - for (s32 k=0; k"; + + case 5: + // GUID token + P += 16; +#ifdef BIN_DBG + printf("skipping guid token\n"); +#endif + return ""; + + case 6: + len = readBinDWord(); + P += (len * 4); +#ifdef BIN_DBG + printf("skipping integer list of %d integers\n", len); +#endif + return ""; + + case 7: + len = readBinDWord(); + P += (len * FloatSize); +#ifdef BIN_DBG + printf("skipping integer list of %d floats of %d bits\n", len, FloatSize); +#endif + return ""; + + case 10: + return "{"; + case 11: + return "}"; + case 31: + return "template"; + } + } + + // process text-formatted file + else + { findNextNoneWhiteSpace(); if (P >= End) @@ -1431,6 +1876,7 @@ s.append(P[0]); ++P; } + } return s; } @@ -1440,6 +1886,8 @@ // and ignores comments void CXFileReader::findNextNoneWhiteSpaceNumber() { + if (binary) return; + while(1) { while(P < End && P[0]!='-' && @@ -1463,6 +1909,8 @@ // places pointer to next begin of a token, and ignores comments void CXFileReader::findNextNoneWhiteSpace() { + if (binary) return; + while(1) { while(P < End && (P[0]==' ' || P[0]=='\n' || P[0]=='\r' || P[0]=='\t')) @@ -1483,6 +1931,8 @@ void CXFileReader::readUntilEndOfLine() { + if (binary) return; + while(P < End) { if (P[0] == '\n') @@ -1532,7 +1982,7 @@ if (frame.Name != "") { char tmp[255]; - sprintf(tmp, "CXFileReader: Frame %s ", frame.Name); + sprintf(tmp, "CXFileReader: Frame %s ", frame.Name.c_str()); os::Printer::log(tmp); for (int i=0; i<4; ++i) { @@ -1573,6 +2023,53 @@ return ftmp; } + +inline u16 CXFileReader::readBinWord() +{ + u8 *Q = (u8 *)P; + + u16 tmp = 0; + tmp = Q[0] + (Q[1] << 8); P += 2; + return tmp; +} + +inline u32 CXFileReader::readBinDWord() +{ + u8 *Q = (u8 *)P; + + u32 tmp = 0; + tmp = Q[0] + (Q[1] << 8) + (Q[2] << 16) + (Q[3] << 24); P += 4; + return tmp; +} + +inline u32 CXFileReader::readBinInt() +{ + u16 tok; + u32 count, ret; + + tok = readBinWord(); + count = readBinDWord(); + ret = readBinDWord(); + + return ret; +} + +inline f32 CXFileReader::readBinFloat() +{ + if (FloatSize == 8) + { + char tmp[8]; + memcpy(tmp, P, 8); P += 8; + return (f32)(*(f64 *)tmp); + } + else + { + char tmp[4]; + memcpy(tmp, P, 4); P += 4; + return *(f32 *)tmp; + } +} + } // end namespace scene } // end namespace irr --- Irrlicht.old/CXFileReader.h 2005-08-20 21:17:52.000000000 +0200 +++ Irrlicht/CXFileReader.h 2005-12-18 14:12:01.000000000 +0100 @@ -252,6 +252,11 @@ s32 readInt(); f32 readFloat(); + u16 readBinWord(); + u32 readBinDWord(); + u32 readBinInt(); + f32 readBinFloat(); + bool parseDataObjectTemplate(); bool parseDataObjectFrame(SXFrame &frame); bool parseDataObjectTransformationMatrix(core::matrix4 &mat); @@ -282,6 +287,8 @@ s32 MajorVersion; s32 MinorVersion; + bool binary; + c8* Buffer; s32 Size; c8 FloatSize;