obj file loader now allows using mtl files with spaces in the filename.

mtllib commands previously used only the first word, now they use the rest of the line.
Different obj format descriptions describe the mtllib command in 2 different ways:
- http://paulbourke.net says it can load several mtl files separated by spaces
- Wikipedia says it can load one mtl file (but there can be several mtllib commands)
We previously loaded 1 file - using the name up to the first space character, so it basically was not correct for either solution. We now go with Wikipedia, because it allows using space in filenames and I tested several other tools and they all handled it like this.

Also COBJMeshFileLoader::copyLine no longer copies the newline character (didn't do that always anyway and we don't need it)


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6275 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2021-12-22 16:19:59 +00:00
parent e037502141
commit e7c7e36347
2 changed files with 15 additions and 7 deletions

@ -1,5 +1,8 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- obj file loader now allows using mtl files with spaces in the filename.
Note that this means it no longer handles obj files which have multiple mtl files behind the mtllib command.
But Irrlicht ignored all but the first name anyway and this way of handling mtllib commands seems to be more common.
- Many defines changed because they were using names which are reserved identifiers in c++. - Many defines changed because they were using names which are reserved identifiers in c++.
Mostly it's about replacing __IRRxxx or _IRRxxx identifiers by versions without underscores Mostly it's about replacing __IRRxxx or _IRRxxx identifiers by versions without underscores
Sometimes underscores at end also got removed. Sometimes underscores at end also got removed.

@ -114,12 +114,18 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
{ {
if (useMaterials) if (useMaterials)
{ {
c8 name[WORD_BUFFER_LENGTH]; // Bit fuzzy definition. Some doc (http://paulbourke.net) says there can be more then one file and they are separated by spaces
bufPtr = goAndCopyNextWord(name, bufPtr, WORD_BUFFER_LENGTH, bufEnd); // Other doc (Wikipedia) says it's one file. Which does allow loading mtl files with spaces in the name.
// Other tools I tested seem to go with the Wikipedia definition
// Irrlicht did just use first word in Irrlicht 1.8, but with 1.9 we switch to allowing filenames with spaces
// If this turns out to cause troubles we can maybe try to catch those cases by looking for ".mtl " inside the string
const c8 * inBuf = goNextWord(bufPtr, bufEnd, false);
core::stringc name = copyLine(inBuf, bufEnd);
#ifdef _IRR_DEBUG_OBJ_LOADER_ #ifdef _IRR_DEBUG_OBJ_LOADER_
os::Printer::log("Reading material file",name); os::Printer::log("Reading material file",name);
#endif #endif
readMTL(name, relPath); readMTL(name.c_str(), relPath);
} }
} }
break; break;
@ -545,7 +551,7 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, const io::path& relPath)
const long filesize = mtlReader->getSize(); const long filesize = mtlReader->getSize();
if (!filesize) if (!filesize)
{ {
os::Printer::log("Skipping empty material file", realFile, ELL_WARNING); os::Printer::log("Skipping empty material file", realFile, ELL_INFORMATION); // it's fine some tools export empty mtl files
mtlReader->drop(); mtlReader->drop();
return; return;
} }
@ -871,12 +877,11 @@ core::stringc COBJMeshFileLoader::copyLine(const c8* inBuf, const c8* bufEnd)
const c8* ptr = inBuf; const c8* ptr = inBuf;
while (ptr<bufEnd) while (ptr<bufEnd)
{ {
if (*ptr=='\n' || *ptr=='\r') if (*ptr=='\n' || *ptr=='\r') // not copying the line end character
break; break;
++ptr; ++ptr;
} }
// we must avoid the +1 in case the array is used up return core::stringc(inBuf, (u32)(ptr-inBuf));
return core::stringc(inBuf, (u32)(ptr-inBuf+((ptr < bufEnd) ? 1 : 0)));
} }