Bug found in both the Irrlicht SDK 1.5 release and the latest SVN i downloaded this evening ( Irrlicht Engine version 1.6 SVN ) .
This had been doing my head in for sometime, though i'd avoided finding the bug and fixing it by using the Blitz exporter and loading up B3D models.
But this week i came across a couple of models that just refused to load up after exporting them to B3D format from Milkshape.
As i've spent plenty of time in the past writing various plugins for milkshape i decided it was time to hunt down the nasty bug and get the MS3D Loader working again.
Turns out it was a very minor problem and to be honest i can see why it had been missed as the MS3D V1.84 file spec documention is not crystal clear about the matter.
From the MS3D V1.84 file specs:
Turns out that the "hasModelComment" struct does NOT include an 'index'. Why? well probably because it has either 0 or 1 comments which is about the entire model. So no need for an index.// Then comes the numer of group comments
unsigned int nNumGroupComments; // 4 bytes
//
// Then come nNumGroupComments times group comments, which are dynamic, because the comment can be any length
//
typedef struct
{
int index; // index of group, material or joint
int commentLength; // length of comment (terminating '\0' is not saved), "MC" has comment length of 2 (not 3)
char comment[commentLength]; // comment
} ms3d_comment_t;
// Then comes the number of material comments
int nNumMaterialComments; // 4 bytes
//
// Then come nNumMaterialComments times material comments, which are dynamic, because the comment can be any length
//
// Then comes the number of joint comments
int nNumJointComments; // 4 bytes
//
// Then come nNumJointComments times joint comments, which are dynamic, because the comment can be any length
//
// Then comes the number of model comments, which is always 0 or 1
int nHasModelComment; // 4 bytes
//
// Then come nHasModelComment times model comments, which are dynamic, because the comment can be any length
//
File: CMS3DMeshFileLoader.cpp
Revision 2410:
Line: 568
Code: Select all
pPtr += sizeof(s32); // index
Code: Select all
if (j<3) pPtr += sizeof(s32); // index
Thats inside this section of code:
Code: Select all
for (u32 j=0; j<4; ++j) // four comment groups
{
#ifdef _IRR_DEBUG_MS3D_LOADER_
os::Printer::log("Skipping comment group", core::stringc(j+1).c_str());
#endif
u32 numComments = *(u32*)pPtr;
#ifdef __BIG_ENDIAN__
numComments = os::Byteswap::byteswap(numComments);
#endif
pPtr += sizeof(u32);
for (i=0; i<numComments; ++i)
{
pPtr += sizeof(s32); // index
s32 commentLength = *(s32*)pPtr;
#ifdef __BIG_ENDIAN__
commentLength = os::Byteswap::byteswap(commentLength);
#endif
pPtr += sizeof(s32);
pPtr += commentLength;
}
if (pPtr > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
}