Make .bullet serialization mode robust:

Deal with broken DNA serialization. Bullet 2.76 release revision 2035 - 2046 was broken, and this includes the Maya Dynamica plugin.
Added some workaround to deal with the broken .bullet files, instead of crashing.
This commit is contained in:
erwin.coumans
2010-03-02 09:32:34 +00:00
parent c517f14dd4
commit 8fbe399ea4
19 changed files with 741 additions and 577 deletions

View File

@@ -200,6 +200,24 @@ void bFile::parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLengt
mFileDNA = new bDNA();
mFileDNA->init(blenderData+sdnaPos, mFileLen-sdnaPos, (mFlags & FD_ENDIAN_SWAP)!=0);
if (mVersion==276)
{
int i;
for (i=0;i<mFileDNA->getNumNames();i++)
{
if (strcmp(mFileDNA->getName(i),"int")==0)
{
mFlags |= FD_BROKEN_DNA;
}
}
if ((mFlags&FD_BROKEN_DNA)!=0)
{
printf("warning: fixing some broken DNA version\n");
}
}
if (verboseDumpAllTypes)
{
mFileDNA->dumpTypeDefinitions();
@@ -211,7 +229,7 @@ void bFile::parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLengt
mMemoryDNA->init(memDna,memDnaLength,littleEndian==0);
///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files
@@ -276,6 +294,34 @@ char* bFile::readStruct(char *head, bChunkInd& dataChunk)
oldType = mFileDNA->getType(oldStruct[0]);
oldLen = mFileDNA->getLength(oldStruct[0]);
if ((mFlags&FD_BROKEN_DNA)!=0)
{
if ((strcmp(oldType,"btQuantizedBvhNodeData")==0)&&oldLen==20)
{
return 0;
}
if ((strcmp(oldType,"btShortIntIndexData")==0))
{
int allocLen = 2;
char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1);
short* dest = (short*) dataAlloc;
const short* src = (short*) head;
for (int i=0;i<dataChunk.nr;i++)
{
dest[i] = src[i];
if (mFlags &FD_ENDIAN_SWAP)
{
SWITCH_SHORT(dest[i]);
}
}
addDataBlock(dataAlloc);
return dataAlloc;
}
}
///don't try to convert Link block data, just memcpy it. Other data can be converted.
if (strcmp("Link",oldType)!=0)
{
@@ -507,7 +553,7 @@ void bFile::swapData(char *data, short type, int arraySize)
void bFile::safeSwapPtr(char *dst, char *src)
void bFile::safeSwapPtr(char *dst, const char *src)
{
int ptrFile = mFileDNA->getPointerSize();
int ptrMem = mMemoryDNA->getPointerSize();
@@ -535,8 +581,12 @@ void bFile::safeSwapPtr(char *dst, char *src)
//deal with pointers the Blender .blend style way, see
//readfile.c in the Blender source tree
long64 longValue = *((long64*)src);
//endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros
if (mFlags & FD_ENDIAN_SWAP)
SWITCH_LONGINT(longValue);
*((int*)dst) = (int)(longValue>>3);
}
}
else if (ptrMem==8 && ptrFile==4)
{
@@ -576,9 +626,18 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c
const char* type = mFileDNA->getType(dna_addr[0]);
const char* name = mFileDNA->getName(dna_addr[1]);
int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]);
int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]);
if ((mFlags&FD_BROKEN_DNA)!=0)
{
if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0))
{
eleLen = 0;
}
}
if (strcmp(lookupName, name)==0)
{
//int arrayLenold = mFileDNA->getArraySize((char*)name.c_str());
@@ -739,7 +798,7 @@ void bFile::resolvePointersMismatch()
// printf("pointer not found: %x\n",cur);
}
}
for (i=0;i< m_pointerPtrFixupArray.size();i++)
for (i=0;i< m_pointerPtrFixupArray.size();i++)
{
char* cur= m_pointerPtrFixupArray.at(i);
void** ptrptr = (void**)cur;
@@ -751,30 +810,32 @@ void bFile::resolvePointersMismatch()
void **array= (void**)(*(ptrptr));
int ptrMem = mMemoryDNA->getPointerSize();
int ptrFile = mFileDNA->getPointerSize();
int n=0, n2=0;
int swapoffs = 2;
void *np = array[n];
while(np)
int n=0;
void *lookup = array[n];
if (lookup)
{
if (ptrMem > ptrFile)
char *oldPtr = (char*)array;
btAlignedObjectArray<btPointerUid> pointers;
while(lookup)
{
safeSwapPtr((char*)&array[n2], (char*)&array[n]);
np = findLibPointer(array[n2]);
btPointerUid dp = {0};
safeSwapPtr((char*)dp.m_uniqueIds, (char*)(oldPtr + (n * ptrFile)));
lookup = findLibPointer(dp.m_ptr);
if (!lookup) break;
pointers.push_back(dp);
++n;
}
else if (ptrMem < ptrFile)
{
safeSwapPtr((char*)&array[n], (char*)&array[n2]);
np = findLibPointer(array[n]);
}
else
np = findLibPointer(array[n]);
if (np)
array[n] = np;
++n;
n2 += swapoffs;
for (int j=0; j<n; ++j)
{
array[j] = findLibPointer(pointers[j].m_ptr);
assert(array[j]);
}
}
}
}
@@ -1202,8 +1263,11 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl
{
long64 oldPtr =0;
memcpy(&oldPtr, &head.m_uniqueInts[0], 8);
if (swap)
SWITCH_LONGINT(oldPtr);
chunk.m_uniqueInt = (int)(oldPtr >> 3);
}
chunk.dna_nr = head.dna_nr;
chunk.nr = head.nr;