Improve the loading of serialized Bullet files, so that

after 'loadFileFromMemory' you can save the existing memory back to disk converted to native architecture endianness.
Fixed a bug that prevented big endian machines to load cloth data (due to wrong endian swap of pointer array)
Also improved the 'preswap' so that you can swap endianness on big endian machines (to little endian)
This commit is contained in:
erwin.coumans
2012-11-10 00:51:51 +00:00
parent f35621eb01
commit c4db79791c
5 changed files with 90 additions and 18 deletions

View File

@@ -368,8 +368,11 @@ void bDNA::init(char *data, int len, bool swap)
// Parse names
if (swap) dataLen = ChunkUtils::swapInt(*intPtr);
else dataLen = *intPtr;
if (swap)
{
*intPtr = ChunkUtils::swapInt(*intPtr);
}
dataLen = *intPtr;
intPtr++;
cp = (char*)intPtr;
@@ -407,8 +410,11 @@ void bDNA::init(char *data, int len, bool swap)
intPtr = (int*)cp;
assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
if (swap) dataLen = ChunkUtils::swapInt(*intPtr);
else dataLen = *intPtr;
if (swap)
{
*intPtr = ChunkUtils::swapInt(*intPtr);
}
dataLen = *intPtr;
intPtr++;
cp = (char*)intPtr;
@@ -467,8 +473,11 @@ void bDNA::init(char *data, int len, bool swap)
cp = (char*)intPtr;
assert(strncmp(cp, "STRC", 4)==0); intPtr++;
if (swap) dataLen = ChunkUtils::swapInt(*intPtr);
else dataLen = *intPtr;
if (swap)
{
*intPtr = ChunkUtils::swapInt(*intPtr);
}
dataLen = *intPtr;
intPtr++;

View File

@@ -241,8 +241,12 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
mFileDNA = new bDNA();
///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary
mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0);
if (mVersion==276)
{
int i;
@@ -286,6 +290,7 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
//printf ("Warning, file DNA is newer than built in.");
}
mFileDNA->initCmpFlags(mMemoryDNA);
parseData();
@@ -304,6 +309,22 @@ void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag)
{
char *data = head;
short *strc = mFileDNA->getStruct(dataChunk.dna_nr);
const char s[] = "SoftBodyMaterialData";
int szs = sizeof(s);
if (strncmp((char*)&dataChunk.code,"ARAY",4)==0)
{
short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
char *oldType = mFileDNA->getType(oldStruct[0]);
if (strncmp(oldType,s,szs)==0)
{
return;
}
}
int len = mFileDNA->getLength(strc[0]);
for (int i=0; i<dataChunk.nr; i++)
@@ -353,6 +374,7 @@ void bFile::swapLen(char *dataPtr)
if ((c->code & 0xFFFF)==0)
c->code >>=16;
SWITCH_INT(c->len);
SWITCH_INT(c->dna_nr);
SWITCH_INT(c->nr);
@@ -526,17 +548,35 @@ void bFile::swapDNA(char* ptr)
}
void bFile::writeFile(const char* fileName)
{
FILE* f = fopen(fileName,"wb");
fwrite(mFileBuffer,1,mFileLen,f);
fclose(f);
}
void bFile::preSwap(const char* fileName)
void bFile::preSwap()
{
const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
//FD_ENDIAN_SWAP
//byte 8 determines the endianness of the file, little (v) versus big (V)
int littleEndian= 1;
littleEndian= ((char*)&littleEndian)[0];
if (mFileBuffer[8]=='V')
{
mFileBuffer[8]='v';
}
else
{
mFileBuffer[8]='V';
}
mDataStart = 12;
@@ -547,6 +587,8 @@ void bFile::preSwap(const char* fileName)
dataChunk.code = 0;
bool ignoreEndianFlag = true;
//we always want to swap here
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
//dataPtr += ChunkUtils::getOffset(mFlags);
char *dataPtrHead = 0;
@@ -563,6 +605,7 @@ void bFile::preSwap(const char* fileName)
{
//if (dataChunk.code == DNA1) break;
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
swapLen(dataPtr);
if (dataChunk.dna_nr>=0)
{
@@ -589,9 +632,6 @@ void bFile::preSwap(const char* fileName)
mFlags |= FD_ENDIAN_SWAP;
}
FILE* f = fopen(fileName,"wb");
fwrite(mFileBuffer,1,mFileLen,f);
fclose(f);
}
@@ -617,6 +657,7 @@ char* bFile::readStruct(char *head, bChunkInd& dataChunk)
oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
oldType = mFileDNA->getType(oldStruct[0]);
oldLen = mFileDNA->getLength(oldStruct[0]);
if ((mFlags&FD_BROKEN_DNA)!=0)
@@ -1579,6 +1620,7 @@ void bFile::writeChunks(FILE* fp, bool fixupPointers)
}
// ----------------------------------------------------- //
int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
{

View File

@@ -155,7 +155,8 @@ namespace bParse {
return mVersion;
}
//pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped
void preSwap(const char* fileName);
void preSwap();
void writeFile(const char* fileName);
};
}

View File

@@ -133,6 +133,11 @@ void btBulletFile::parseData()
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
if (mFlags &FD_ENDIAN_SWAP)
swapLen(dataPtr);
//dataPtr += ChunkUtils::getOffset(mFlags);
char *dataPtrHead = 0;
@@ -219,10 +224,13 @@ void btBulletFile::parseData()
printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
}
// next please!
dataPtr += seek;
seek = getNextBlock(&dataChunk, dataPtr, mFlags);
if (mFlags &FD_ENDIAN_SWAP)
swapLen(dataPtr);
if (seek < 0)
break;
}
@@ -334,6 +342,15 @@ void btBulletFile::parse(int verboseMode)
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
}
#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
//the parsing will convert to cpu endian
mFlags &=~FD_ENDIAN_SWAP;
int littleEndian= 1;
littleEndian= ((char*)&littleEndian)[0];
mFileBuffer[8] = littleEndian?'v':'V';
}
// experimental

View File

@@ -42,12 +42,15 @@ bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapF
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
bool result = loadFileFromMemory(bulletFile2);
//now you could save the file in 'native' format using
//bulletFile2->writeFile("native.bullet");
if (preSwapFilenameOut)
bulletFile2->preSwap(preSwapFilenameOut);
{
bulletFile2->preSwap();
bulletFile2->writeFile(preSwapFilenameOut);
}
delete bulletFile2;