allow the Bullet world importer to save a copy with swapped endianness
See http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=8191
This commit is contained in:
@@ -765,7 +765,7 @@ void SerializeDemo::initPhysics()
|
||||
|
||||
|
||||
|
||||
if (!m_fileLoader->loadFile("testFile.bullet"))
|
||||
if (!m_fileLoader->loadFile("testFile.bullet", "testFileSwappedEndianness.bullet"))
|
||||
// if (!m_fileLoader->loadFile("../SoftDemo/testFile.bullet"))
|
||||
{
|
||||
///create a few basic rigid bodies and save them to testFile.bullet
|
||||
|
||||
@@ -300,7 +300,7 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
|
||||
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
void bFile::swap(char *head, bChunkInd& dataChunk)
|
||||
void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag)
|
||||
{
|
||||
char *data = head;
|
||||
short *strc = mFileDNA->getStruct(dataChunk.dna_nr);
|
||||
@@ -308,18 +308,302 @@ void bFile::swap(char *head, bChunkInd& dataChunk)
|
||||
|
||||
for (int i=0; i<dataChunk.nr; i++)
|
||||
{
|
||||
swapStruct(dataChunk.dna_nr, data);
|
||||
swapStruct(dataChunk.dna_nr, data,ignoreEndianFlag);
|
||||
data+=len;
|
||||
}
|
||||
}
|
||||
|
||||
void bFile::swapLen(char *dataPtr)
|
||||
{
|
||||
const bool VOID_IS_8 = ((sizeof(void*)==8));
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
if (mFlags &FD_BITS_VARIES)
|
||||
{
|
||||
bChunkPtr4*c = (bChunkPtr4*) dataPtr;
|
||||
if ((c->code & 0xFFFF)==0)
|
||||
c->code >>=16;
|
||||
SWITCH_INT(c->len);
|
||||
SWITCH_INT(c->dna_nr);
|
||||
SWITCH_INT(c->nr);
|
||||
} else
|
||||
{
|
||||
bChunkPtr8* c = (bChunkPtr8*) dataPtr;
|
||||
if ((c->code & 0xFFFF)==0)
|
||||
c->code >>=16;
|
||||
SWITCH_INT(c->len);
|
||||
SWITCH_INT(c->dna_nr);
|
||||
SWITCH_INT(c->nr);
|
||||
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (mFlags &FD_BITS_VARIES)
|
||||
{
|
||||
bChunkPtr8*c = (bChunkPtr8*) dataPtr;
|
||||
if ((c->code & 0xFFFF)==0)
|
||||
c->code >>=16;
|
||||
SWITCH_INT(c->len);
|
||||
SWITCH_INT(c->dna_nr);
|
||||
SWITCH_INT(c->nr);
|
||||
|
||||
} else
|
||||
{
|
||||
bChunkPtr4* c = (bChunkPtr4*) dataPtr;
|
||||
if ((c->code & 0xFFFF)==0)
|
||||
c->code >>=16;
|
||||
SWITCH_INT(c->len);
|
||||
SWITCH_INT(c->dna_nr);
|
||||
SWITCH_INT(c->nr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void bFile::swapDNA(char* ptr)
|
||||
{
|
||||
bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0);
|
||||
|
||||
char* data = &ptr[20];
|
||||
// void bDNA::init(char *data, int len, bool swap)
|
||||
int *intPtr=0;short *shtPtr=0;
|
||||
char *cp = 0;int dataLen =0;long nr=0;
|
||||
intPtr = (int*)data;
|
||||
|
||||
/*
|
||||
SDNA (4 bytes) (magic number)
|
||||
NAME (4 bytes)
|
||||
<nr> (4 bytes) amount of names (int)
|
||||
<string>
|
||||
<string>
|
||||
*/
|
||||
|
||||
if (strncmp(data, "SDNA", 4)==0)
|
||||
{
|
||||
// skip ++ NAME
|
||||
intPtr++; intPtr++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Parse names
|
||||
if (swap)
|
||||
dataLen = ChunkUtils::swapInt(*intPtr);
|
||||
else
|
||||
dataLen = *intPtr;
|
||||
|
||||
*intPtr = ChunkUtils::swapInt(*intPtr);
|
||||
intPtr++;
|
||||
|
||||
cp = (char*)intPtr;
|
||||
int i;
|
||||
for ( i=0; i<dataLen; i++)
|
||||
{
|
||||
while (*cp)cp++;
|
||||
cp++;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
nr= (long)cp;
|
||||
//long mask=3;
|
||||
nr= ((nr+3)&~3)-nr;
|
||||
while (nr--)
|
||||
{
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TYPE (4 bytes)
|
||||
<nr> amount of types (int)
|
||||
<string>
|
||||
<string>
|
||||
*/
|
||||
|
||||
intPtr = (int*)cp;
|
||||
assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
|
||||
|
||||
if (swap)
|
||||
dataLen = ChunkUtils::swapInt(*intPtr);
|
||||
else
|
||||
dataLen = *intPtr;
|
||||
|
||||
*intPtr = ChunkUtils::swapInt(*intPtr);
|
||||
|
||||
intPtr++;
|
||||
|
||||
cp = (char*)intPtr;
|
||||
for ( i=0; i<dataLen; i++)
|
||||
{
|
||||
while (*cp)cp++;
|
||||
cp++;
|
||||
}
|
||||
|
||||
{
|
||||
nr= (long)cp;
|
||||
// long mask=3;
|
||||
nr= ((nr+3)&~3)-nr;
|
||||
while (nr--)
|
||||
{
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TLEN (4 bytes)
|
||||
<len> (short) the lengths of types
|
||||
<len>
|
||||
*/
|
||||
|
||||
// Parse type lens
|
||||
intPtr = (int*)cp;
|
||||
assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
|
||||
|
||||
|
||||
shtPtr = (short*)intPtr;
|
||||
for ( i=0; i<dataLen; i++, shtPtr++)
|
||||
{
|
||||
//??????if (swap)
|
||||
shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
|
||||
}
|
||||
|
||||
if (dataLen & 1)
|
||||
shtPtr++;
|
||||
|
||||
/*
|
||||
STRC (4 bytes)
|
||||
<nr> amount of structs (int)
|
||||
<typenr>
|
||||
<nr_of_elems>
|
||||
<typenr>
|
||||
<namenr>
|
||||
<typenr>
|
||||
<namenr>
|
||||
*/
|
||||
|
||||
intPtr = (int*)shtPtr;
|
||||
cp = (char*)intPtr;
|
||||
assert(strncmp(cp, "STRC", 4)==0);
|
||||
intPtr++;
|
||||
|
||||
if (swap)
|
||||
dataLen = ChunkUtils::swapInt(*intPtr);
|
||||
else
|
||||
dataLen = *intPtr;
|
||||
|
||||
*intPtr = ChunkUtils::swapInt(*intPtr);
|
||||
|
||||
intPtr++;
|
||||
|
||||
|
||||
shtPtr = (short*)intPtr;
|
||||
for ( i=0; i<dataLen; i++)
|
||||
{
|
||||
|
||||
//if (swap)
|
||||
{
|
||||
int len = shtPtr[1];
|
||||
|
||||
shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
|
||||
shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
|
||||
|
||||
shtPtr+= 2;
|
||||
|
||||
for (int a=0; a<len; a++, shtPtr+=2)
|
||||
{
|
||||
shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
|
||||
shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
|
||||
}
|
||||
}
|
||||
// else
|
||||
// shtPtr+= (2*shtPtr[1])+2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void bFile::preSwap(const char* fileName)
|
||||
{
|
||||
|
||||
const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
|
||||
//FD_ENDIAN_SWAP
|
||||
//byte 8 determines the endianness of the file, little (v) versus big (V)
|
||||
if (mFileBuffer[8]=='V')
|
||||
mFileBuffer[8]='v';
|
||||
else
|
||||
mFileBuffer[8]='V';
|
||||
|
||||
|
||||
mDataStart = 12;
|
||||
|
||||
char *dataPtr = mFileBuffer+mDataStart;
|
||||
|
||||
bChunkInd dataChunk;
|
||||
dataChunk.code = 0;
|
||||
bool ignoreEndianFlag = true;
|
||||
|
||||
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
//dataPtr += ChunkUtils::getOffset(mFlags);
|
||||
char *dataPtrHead = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// one behind
|
||||
if (dataChunk.code == SDNA || dataChunk.code==DNA1 || dataChunk.code == TYPE || dataChunk.code == TLEN || dataChunk.code==STRC)
|
||||
{
|
||||
|
||||
swapDNA(dataPtr);
|
||||
break;
|
||||
} else
|
||||
{
|
||||
//if (dataChunk.code == DNA1) break;
|
||||
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
|
||||
swapLen(dataPtr);
|
||||
if (dataChunk.dna_nr>=0)
|
||||
{
|
||||
swap(dataPtrHead, dataChunk,ignoreEndianFlag);
|
||||
} else
|
||||
{
|
||||
printf("unknown chunk\n");
|
||||
}
|
||||
}
|
||||
|
||||
// next please!
|
||||
dataPtr += seek;
|
||||
|
||||
seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
if (seek < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mFlags & FD_ENDIAN_SWAP)
|
||||
{
|
||||
mFlags &= ~FD_ENDIAN_SWAP;
|
||||
} else
|
||||
{
|
||||
mFlags |= FD_ENDIAN_SWAP;
|
||||
}
|
||||
|
||||
FILE* f = fopen(fileName,"wb");
|
||||
fwrite(mFileBuffer,1,mFileLen,f);
|
||||
fclose(f);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
char* bFile::readStruct(char *head, bChunkInd& dataChunk)
|
||||
{
|
||||
bool ignoreEndianFlag = false;
|
||||
|
||||
if (mFlags & FD_ENDIAN_SWAP)
|
||||
swap(head, dataChunk);
|
||||
swap(head, dataChunk, ignoreEndianFlag);
|
||||
|
||||
|
||||
|
||||
@@ -562,9 +846,9 @@ static void getElement(int arrayLen, const char *cur, const char *old, char *old
|
||||
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
void bFile::swapData(char *data, short type, int arraySize)
|
||||
void bFile::swapData(char *data, short type, int arraySize,bool ignoreEndianFlag)
|
||||
{
|
||||
if (mFlags &FD_ENDIAN_SWAP)
|
||||
if (ignoreEndianFlag || (mFlags &FD_ENDIAN_SWAP))
|
||||
{
|
||||
if (type == 2 || type == 3)
|
||||
{
|
||||
@@ -770,7 +1054,7 @@ char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupTy
|
||||
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
void bFile::swapStruct(int dna_nr, char *data)
|
||||
void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag)
|
||||
{
|
||||
if (dna_nr == -1) return;
|
||||
|
||||
@@ -795,13 +1079,13 @@ void bFile::swapStruct(int dna_nr, char *data)
|
||||
int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
|
||||
if (arrayLen==1)
|
||||
{
|
||||
swapStruct(old_nr,buf);
|
||||
swapStruct(old_nr,buf,ignoreEndianFlag);
|
||||
} else
|
||||
{
|
||||
char* tmpBuf = buf;
|
||||
for (int i=0;i<arrayLen;i++)
|
||||
{
|
||||
swapStruct(old_nr,tmpBuf);
|
||||
swapStruct(old_nr,tmpBuf,ignoreEndianFlag);
|
||||
tmpBuf+=size/arrayLen;
|
||||
}
|
||||
}
|
||||
@@ -811,7 +1095,7 @@ void bFile::swapStruct(int dna_nr, char *data)
|
||||
//int arrayLenOld = mFileDNA->getArraySize(name);
|
||||
int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
|
||||
//assert(arrayLenOld == arrayLen);
|
||||
swapData(buf, strc[0], arrayLen);
|
||||
swapData(buf, strc[0], arrayLen,ignoreEndianFlag);
|
||||
}
|
||||
buf+=size;
|
||||
}
|
||||
@@ -1301,8 +1585,10 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl
|
||||
bool swap = false;
|
||||
bool varies = false;
|
||||
|
||||
if (flags &FD_ENDIAN_SWAP) swap = true;
|
||||
if (flags &FD_BITS_VARIES) varies = true;
|
||||
if (flags &FD_ENDIAN_SWAP)
|
||||
swap = true;
|
||||
if (flags &FD_BITS_VARIES)
|
||||
varies = true;
|
||||
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
|
||||
@@ -96,12 +96,11 @@ namespace bParse {
|
||||
char* getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos);
|
||||
|
||||
|
||||
void swap(char *head, class bChunkInd& ch);
|
||||
|
||||
void swapData(char *data, short type, int arraySize);
|
||||
void swapStruct(int dna_nr, char *data);
|
||||
|
||||
|
||||
void swap(char *head, class bChunkInd& ch, bool ignoreEndianFlag);
|
||||
void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag);
|
||||
void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag);
|
||||
void swapLen(char *dataPtr);
|
||||
void swapDNA(char* ptr);
|
||||
|
||||
|
||||
char* readStruct(char *head, class bChunkInd& chunk);
|
||||
@@ -155,8 +154,9 @@ 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);
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -37,12 +37,18 @@ btBulletWorldImporter::~btBulletWorldImporter()
|
||||
}
|
||||
|
||||
|
||||
bool btBulletWorldImporter::loadFile( const char* fileName)
|
||||
bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapFilenameOut)
|
||||
{
|
||||
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
||||
|
||||
|
||||
|
||||
|
||||
bool result = loadFileFromMemory(bulletFile2);
|
||||
|
||||
if (preSwapFilenameOut)
|
||||
bulletFile2->preSwap(preSwapFilenameOut);
|
||||
|
||||
delete bulletFile2;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -47,7 +47,9 @@ public:
|
||||
|
||||
virtual ~btBulletWorldImporter();
|
||||
|
||||
bool loadFile(const char* fileName);
|
||||
///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness
|
||||
///this pre-swapped file can be loaded without swapping on a target platform of different endianness
|
||||
bool loadFile(const char* fileName, const char* preSwapFilenameOut=0);
|
||||
|
||||
///the memoryBuffer might be modified (for example if endian swaps are necessary)
|
||||
bool loadFileFromMemory(char *memoryBuffer, int len);
|
||||
|
||||
Reference in New Issue
Block a user