Added some improvements on Bullet serialization:
Introduced generated unique id's, instead of the pointer address to avoid 64bit->32bit truncation issues Use serializer->getUniquePointer instead of directly using a pointer moved ChunkUtils::getNextBlock to bFile::getNextBlock. Moved 'TEST_BACKWARD_FORWARD_COMPATIBILITY' to bDNA.cpp. Enable the define for further testing of .bullet format Removed duplicate definitions and use the one in LinearMath/btSerialization.h
This commit is contained in:
@@ -75,7 +75,7 @@ void bBlenderFile::parseData()
|
||||
|
||||
|
||||
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
int seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
//dataPtr += ChunkUtils::getOffset(mFlags);
|
||||
char *dataPtrHead = 0;
|
||||
|
||||
@@ -89,7 +89,7 @@ void bBlenderFile::parseData()
|
||||
if (dataChunk.code == SDNA) break;
|
||||
//if (dataChunk.code == DNA1) break;
|
||||
|
||||
// same as (BHEAD+DATA dependancy)
|
||||
// same as (BHEAD+DATA dependency)
|
||||
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
|
||||
char *id = readStruct(dataPtrHead, dataChunk);
|
||||
|
||||
@@ -113,7 +113,7 @@ void bBlenderFile::parseData()
|
||||
// next please!
|
||||
dataPtr += seek;
|
||||
|
||||
seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
if (seek < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -69,125 +69,6 @@ int ChunkUtils::getOffset(int flags)
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
int ChunkUtils::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
|
||||
{
|
||||
bool swap = false;
|
||||
bool varies = false;
|
||||
|
||||
if (flags &FD_ENDIAN_SWAP) swap = true;
|
||||
if (flags &FD_BITS_VARIES) varies = true;
|
||||
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
if (varies)
|
||||
{
|
||||
bChunkPtr4 head;
|
||||
memcpy(&head, dataPtr, sizeof(bChunkPtr4));
|
||||
|
||||
|
||||
bChunkPtr8 chunk;
|
||||
|
||||
chunk.code = head.code;
|
||||
chunk.len = head.len;
|
||||
chunk.old = head.old;
|
||||
chunk.dna_nr = head.dna_nr;
|
||||
chunk.nr = head.nr;
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((chunk.code & 0xFFFF)==0)
|
||||
chunk.code >>=16;
|
||||
|
||||
SWITCH_INT(chunk.len);
|
||||
SWITCH_INT(chunk.dna_nr);
|
||||
SWITCH_INT(chunk.nr);
|
||||
}
|
||||
|
||||
|
||||
memcpy(dataChunk, &chunk, sizeof(bChunkInd));
|
||||
}
|
||||
else
|
||||
{
|
||||
bChunkPtr8 c;
|
||||
memcpy(&c, dataPtr, sizeof(bChunkPtr8));
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((c.code & 0xFFFF)==0)
|
||||
c.code >>=16;
|
||||
|
||||
SWITCH_INT(c.len);
|
||||
SWITCH_INT(c.dna_nr);
|
||||
SWITCH_INT(c.nr);
|
||||
}
|
||||
|
||||
memcpy(dataChunk, &c, sizeof(bChunkInd));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varies)
|
||||
{
|
||||
bChunkPtr8 head;
|
||||
memcpy(&head, dataPtr, sizeof(bChunkPtr8));
|
||||
|
||||
|
||||
bChunkPtr4 chunk;
|
||||
chunk.code = head.code;
|
||||
chunk.len = head.len;
|
||||
|
||||
long64 oldPtr =0;
|
||||
|
||||
memcpy(&oldPtr, &head.old, 8);
|
||||
chunk.old = (int)(oldPtr >> 3);
|
||||
|
||||
chunk.dna_nr = head.dna_nr;
|
||||
chunk.nr = head.nr;
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((chunk.code & 0xFFFF)==0)
|
||||
chunk.code >>=16;
|
||||
|
||||
SWITCH_INT(chunk.len);
|
||||
SWITCH_INT(chunk.dna_nr);
|
||||
SWITCH_INT(chunk.nr);
|
||||
}
|
||||
|
||||
memcpy(dataChunk, &chunk, sizeof(bChunkInd));
|
||||
}
|
||||
else
|
||||
{
|
||||
bChunkPtr4 c;
|
||||
memcpy(&c, dataPtr, sizeof(bChunkPtr4));
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((c.code & 0xFFFF)==0)
|
||||
c.code >>=16;
|
||||
|
||||
SWITCH_INT(c.len);
|
||||
SWITCH_INT(c.dna_nr);
|
||||
SWITCH_INT(c.nr);
|
||||
}
|
||||
memcpy(dataChunk, &c, sizeof(bChunkInd));
|
||||
}
|
||||
}
|
||||
|
||||
if (dataChunk->len < 0)
|
||||
return -1;
|
||||
|
||||
#if 0
|
||||
print ("----------");
|
||||
print (dataChunk->code);
|
||||
print (dataChunk->len);
|
||||
print (dataChunk->old);
|
||||
print (dataChunk->dna_nr);
|
||||
print (dataChunk->nr);
|
||||
#endif
|
||||
return (dataChunk->len+getOffset(flags));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,10 @@ namespace bParse {
|
||||
bChunkPtr4(){}
|
||||
int code;
|
||||
int len;
|
||||
int old;
|
||||
union
|
||||
{
|
||||
int m_uniqueInt;
|
||||
};
|
||||
int dna_nr;
|
||||
int nr;
|
||||
};
|
||||
@@ -45,7 +48,11 @@ namespace bParse {
|
||||
public:
|
||||
bChunkPtr8(){}
|
||||
int code, len;
|
||||
long64 old;
|
||||
union
|
||||
{
|
||||
long64 oldPrev;
|
||||
int m_uniqueInts[2];
|
||||
};
|
||||
int dna_nr, nr;
|
||||
};
|
||||
|
||||
@@ -64,8 +71,6 @@ namespace bParse {
|
||||
class ChunkUtils
|
||||
{
|
||||
public:
|
||||
// buffer offset util
|
||||
static int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags);
|
||||
|
||||
// file chunk offset
|
||||
static int getOffset(int flags);
|
||||
|
||||
@@ -20,6 +20,10 @@ subject to the following restrictions:
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//this define will force traversal of structures, to check backward (and forward) compatibility
|
||||
//#define TEST_BACKWARD_FORWARD_COMPATIBILITY
|
||||
|
||||
|
||||
using namespace bParse;
|
||||
|
||||
|
||||
@@ -213,7 +217,8 @@ void bDNA::initCmpFlags(bDNA *memDNA)
|
||||
// rebuild...
|
||||
mCMPFlags[i] = FDF_STRUCT_NEQU;
|
||||
|
||||
#if 1
|
||||
#ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY
|
||||
|
||||
if (curStruct[1] == oldStruct[1])
|
||||
{
|
||||
// type len same ...
|
||||
|
||||
@@ -19,12 +19,14 @@ subject to the following restrictions:
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bDefines.h"
|
||||
#include "LinearMath/btSerializer.h"
|
||||
|
||||
#define SIZEOFBLENDERHEADER 12
|
||||
#define MAX_ARRAY_LENGTH 512
|
||||
using namespace bParse;
|
||||
|
||||
//this define will force traversal of structures, to check backward (and forward) compatibility
|
||||
//#define TEST_BACKWARD_FORWARD_COMPATIBILITY
|
||||
|
||||
|
||||
int numallocs = 0;
|
||||
|
||||
@@ -262,11 +264,7 @@ char* bFile::readStruct(char *head, bChunkInd& dataChunk)
|
||||
|
||||
|
||||
|
||||
#ifdef TEST_BACKWARD_FORWARD_COMPATIBILITY
|
||||
if (1)
|
||||
#else
|
||||
if (!mFileDNA->flagEqual(dataChunk.dna_nr))
|
||||
#endif
|
||||
{
|
||||
// Ouch! need to rebuild the struct
|
||||
short *oldStruct,*curStruct;
|
||||
@@ -508,7 +506,8 @@ void bFile::swapData(char *data, short type, int arraySize)
|
||||
}
|
||||
|
||||
|
||||
void bFile::swapPtr(char *dst, char *src)
|
||||
|
||||
void bFile::safeSwapPtr(char *dst, char *src)
|
||||
{
|
||||
int ptrFile = mFileDNA->getPointerSize();
|
||||
int ptrMem = mMemoryDNA->getPointerSize();
|
||||
@@ -516,22 +515,52 @@ void bFile::swapPtr(char *dst, char *src)
|
||||
if (!src && !dst)
|
||||
return;
|
||||
|
||||
|
||||
if (ptrFile == ptrMem)
|
||||
{
|
||||
memcpy(dst, src, ptrMem);
|
||||
}
|
||||
else if (ptrMem==4 && ptrFile==8)
|
||||
{
|
||||
long64 longValue = *((long64*)src);
|
||||
*((int*)dst) = (int)(longValue>>3);
|
||||
btPointerUid* oldPtr = (btPointerUid*)src;
|
||||
btPointerUid* newPtr = (btPointerUid*)dst;
|
||||
|
||||
if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
|
||||
{
|
||||
//Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers
|
||||
//so it can be used to distinguish between .blend and .bullet
|
||||
newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
|
||||
} else
|
||||
{
|
||||
//deal with pointers the Blender .blend style way, see
|
||||
//readfile.c in the Blender source tree
|
||||
long64 longValue = *((long64*)src);
|
||||
*((int*)dst) = (int)(longValue>>3);
|
||||
}
|
||||
}
|
||||
else if (ptrMem==8 && ptrFile==4)
|
||||
*((long64*)dst)= *((int*)src);
|
||||
{
|
||||
btPointerUid* oldPtr = (btPointerUid*)src;
|
||||
btPointerUid* newPtr = (btPointerUid*)dst;
|
||||
if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
|
||||
{
|
||||
newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
|
||||
newPtr->m_uniqueIds[1] = 0;
|
||||
} else
|
||||
{
|
||||
*((long64*)dst)= *((int*)src);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("%d %d\n", ptrFile,ptrMem);
|
||||
assert(0 && "Invalid pointer len");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers)
|
||||
{
|
||||
@@ -561,8 +590,7 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c
|
||||
// cast pointers
|
||||
int ptrFile = mFileDNA->getPointerSize();
|
||||
int ptrMem = mMemoryDNA->getPointerSize();
|
||||
|
||||
swapPtr(strcData, data);
|
||||
safeSwapPtr(strcData,data);
|
||||
|
||||
if (fixupPointers)
|
||||
{
|
||||
@@ -577,7 +605,7 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c
|
||||
|
||||
for (int a=0; a<arrayLen; a++)
|
||||
{
|
||||
swapPtr(cpc, cpo);
|
||||
safeSwapPtr(cpc, cpo);
|
||||
m_pointerFixupArray.push_back(cpc);
|
||||
cpc += ptrMem;
|
||||
cpo += ptrFile;
|
||||
@@ -732,12 +760,12 @@ void bFile::resolvePointersMismatch()
|
||||
{
|
||||
if (ptrMem > ptrFile)
|
||||
{
|
||||
swapPtr((char*)&array[n2], (char*)&array[n]);
|
||||
safeSwapPtr((char*)&array[n2], (char*)&array[n]);
|
||||
np = findLibPointer(array[n2]);
|
||||
}
|
||||
else if (ptrMem < ptrFile)
|
||||
{
|
||||
swapPtr((char*)&array[n], (char*)&array[n2]);
|
||||
safeSwapPtr((char*)&array[n], (char*)&array[n2]);
|
||||
np = findLibPointer(array[n]);
|
||||
}
|
||||
else
|
||||
@@ -944,11 +972,7 @@ void bFile::resolvePointers(bool verboseDumpAllBlocks)
|
||||
{
|
||||
const bChunkInd& dataChunk = m_chunks.at(i);
|
||||
|
||||
#ifdef TEST_BACKWARD_FORWARD_COMPATIBILITY
|
||||
if (1)
|
||||
#else
|
||||
if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr))
|
||||
#endif
|
||||
{
|
||||
//dataChunk.len
|
||||
short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
|
||||
@@ -1102,6 +1126,133 @@ void bFile::writeChunks(FILE* fp, bool fixupPointers)
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
|
||||
{
|
||||
bool swap = false;
|
||||
bool varies = false;
|
||||
|
||||
if (flags &FD_ENDIAN_SWAP) swap = true;
|
||||
if (flags &FD_BITS_VARIES) varies = true;
|
||||
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
if (varies)
|
||||
{
|
||||
bChunkPtr4 head;
|
||||
memcpy(&head, dataPtr, sizeof(bChunkPtr4));
|
||||
|
||||
|
||||
bChunkPtr8 chunk;
|
||||
|
||||
chunk.code = head.code;
|
||||
chunk.len = head.len;
|
||||
chunk.m_uniqueInts[0] = head.m_uniqueInt;
|
||||
chunk.m_uniqueInts[1] = 0;
|
||||
chunk.dna_nr = head.dna_nr;
|
||||
chunk.nr = head.nr;
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((chunk.code & 0xFFFF)==0)
|
||||
chunk.code >>=16;
|
||||
|
||||
SWITCH_INT(chunk.len);
|
||||
SWITCH_INT(chunk.dna_nr);
|
||||
SWITCH_INT(chunk.nr);
|
||||
}
|
||||
|
||||
|
||||
memcpy(dataChunk, &chunk, sizeof(bChunkInd));
|
||||
}
|
||||
else
|
||||
{
|
||||
bChunkPtr8 c;
|
||||
memcpy(&c, dataPtr, sizeof(bChunkPtr8));
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((c.code & 0xFFFF)==0)
|
||||
c.code >>=16;
|
||||
|
||||
SWITCH_INT(c.len);
|
||||
SWITCH_INT(c.dna_nr);
|
||||
SWITCH_INT(c.nr);
|
||||
}
|
||||
|
||||
memcpy(dataChunk, &c, sizeof(bChunkInd));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varies)
|
||||
{
|
||||
bChunkPtr8 head;
|
||||
memcpy(&head, dataPtr, sizeof(bChunkPtr8));
|
||||
|
||||
|
||||
bChunkPtr4 chunk;
|
||||
chunk.code = head.code;
|
||||
chunk.len = head.len;
|
||||
|
||||
if (head.m_uniqueInts[0]==head.m_uniqueInts[1])
|
||||
{
|
||||
chunk.m_uniqueInt = head.m_uniqueInts[0];
|
||||
} else
|
||||
{
|
||||
long64 oldPtr =0;
|
||||
memcpy(&oldPtr, &head.m_uniqueInts[0], 8);
|
||||
chunk.m_uniqueInt = (int)(oldPtr >> 3);
|
||||
}
|
||||
|
||||
chunk.dna_nr = head.dna_nr;
|
||||
chunk.nr = head.nr;
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((chunk.code & 0xFFFF)==0)
|
||||
chunk.code >>=16;
|
||||
|
||||
SWITCH_INT(chunk.len);
|
||||
SWITCH_INT(chunk.dna_nr);
|
||||
SWITCH_INT(chunk.nr);
|
||||
}
|
||||
|
||||
memcpy(dataChunk, &chunk, sizeof(bChunkInd));
|
||||
}
|
||||
else
|
||||
{
|
||||
bChunkPtr4 c;
|
||||
memcpy(&c, dataPtr, sizeof(bChunkPtr4));
|
||||
|
||||
if (swap)
|
||||
{
|
||||
if ((c.code & 0xFFFF)==0)
|
||||
c.code >>=16;
|
||||
|
||||
SWITCH_INT(c.len);
|
||||
SWITCH_INT(c.dna_nr);
|
||||
SWITCH_INT(c.nr);
|
||||
}
|
||||
memcpy(dataChunk, &c, sizeof(bChunkInd));
|
||||
}
|
||||
}
|
||||
|
||||
if (dataChunk->len < 0)
|
||||
return -1;
|
||||
|
||||
#if 0
|
||||
print ("----------");
|
||||
print (dataChunk->code);
|
||||
print (dataChunk->len);
|
||||
print (dataChunk->old);
|
||||
print (dataChunk->dna_nr);
|
||||
print (dataChunk->nr);
|
||||
#endif
|
||||
return (dataChunk->len+ChunkUtils::getOffset(flags));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//eof
|
||||
|
||||
|
||||
@@ -64,10 +64,15 @@ namespace bParse {
|
||||
|
||||
bPtrMap mDataPointers;
|
||||
|
||||
|
||||
|
||||
int mFlags;
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// buffer offset util
|
||||
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags);
|
||||
void safeSwapPtr(char *dst, char *src);
|
||||
|
||||
virtual void parseHeader();
|
||||
|
||||
virtual void parseData() = 0;
|
||||
@@ -76,7 +81,7 @@ namespace bParse {
|
||||
void resolvePointersChunk(const bChunkInd& dataChunk, bool verboseDumpAllBlocks);
|
||||
|
||||
void resolvePointersStructRecursive(char *strcPtr, int old_dna, bool verboseDumpAllBlocks, int recursion);
|
||||
void swapPtr(char *dst, char *src);
|
||||
//void swapPtr(char *dst, char *src);
|
||||
|
||||
void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers);
|
||||
void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers);
|
||||
|
||||
@@ -120,7 +120,7 @@ void btBulletFile::parseData()
|
||||
|
||||
|
||||
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
int seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
//dataPtr += ChunkUtils::getOffset(mFlags);
|
||||
char *dataPtrHead = 0;
|
||||
|
||||
@@ -134,7 +134,7 @@ void btBulletFile::parseData()
|
||||
if (dataChunk.code == SDNA) break;
|
||||
//if (dataChunk.code == DNA1) break;
|
||||
|
||||
// same as (BHEAD+DATA dependancy)
|
||||
// same as (BHEAD+DATA dependency)
|
||||
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
|
||||
if (dataChunk.dna_nr>=0)
|
||||
{
|
||||
@@ -196,7 +196,7 @@ void btBulletFile::parseData()
|
||||
// next please!
|
||||
dataPtr += seek;
|
||||
|
||||
seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||
if (seek < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -21,13 +21,8 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "bDefines.h"
|
||||
|
||||
#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J')
|
||||
#define BT_RIGIDBODY_CODE MAKE_ID('R','B','D','Y')
|
||||
#define BT_CONSTRAINT_CODE MAKE_ID('C','O','N','S')
|
||||
#define BT_BOXSHAPE_CODE MAKE_ID('B','O','X','S')
|
||||
#define BT_QUANTIZED_BVH_CODE MAKE_ID('Q','B','V','H')
|
||||
#define BT_TRIANLGE_INFO_MAP MAKE_ID('T','M','A','P')
|
||||
#define BT_SHAPE_CODE MAKE_ID('S','H','A','P')
|
||||
#include "LinearMath/btSerializer.h"
|
||||
|
||||
|
||||
|
||||
namespace bParse {
|
||||
|
||||
@@ -263,11 +263,11 @@ int main(int argc,char** argv)
|
||||
if (isBulletFile)
|
||||
{
|
||||
btBulletFile f(memBuf,len);
|
||||
swap = f.getFlags() & FD_ENDIAN_SWAP;
|
||||
swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
|
||||
} else
|
||||
{
|
||||
bBlenderFile f(memBuf,len);
|
||||
swap = f.getFlags() & FD_ENDIAN_SWAP;
|
||||
swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user