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:
erwin.coumans
2010-02-28 20:50:50 +00:00
parent d5ea1d569f
commit 9acb3d1805
19 changed files with 266 additions and 185 deletions

View File

@@ -75,7 +75,7 @@ void bBlenderFile::parseData()
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
int seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
//dataPtr += ChunkUtils::getOffset(mFlags); //dataPtr += ChunkUtils::getOffset(mFlags);
char *dataPtrHead = 0; char *dataPtrHead = 0;
@@ -89,7 +89,7 @@ void bBlenderFile::parseData()
if (dataChunk.code == SDNA) break; if (dataChunk.code == SDNA) break;
//if (dataChunk.code == DNA1) break; //if (dataChunk.code == DNA1) break;
// same as (BHEAD+DATA dependancy) // same as (BHEAD+DATA dependency)
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
char *id = readStruct(dataPtrHead, dataChunk); char *id = readStruct(dataPtrHead, dataChunk);
@@ -113,7 +113,7 @@ void bBlenderFile::parseData()
// next please! // next please!
dataPtr += seek; dataPtr += seek;
seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); seek = getNextBlock(&dataChunk, dataPtr, mFlags);
if (seek < 0) if (seek < 0)
break; break;
} }

View File

@@ -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));
}

View File

@@ -34,7 +34,10 @@ namespace bParse {
bChunkPtr4(){} bChunkPtr4(){}
int code; int code;
int len; int len;
int old; union
{
int m_uniqueInt;
};
int dna_nr; int dna_nr;
int nr; int nr;
}; };
@@ -45,7 +48,11 @@ namespace bParse {
public: public:
bChunkPtr8(){} bChunkPtr8(){}
int code, len; int code, len;
long64 old; union
{
long64 oldPrev;
int m_uniqueInts[2];
};
int dna_nr, nr; int dna_nr, nr;
}; };
@@ -64,8 +71,6 @@ namespace bParse {
class ChunkUtils class ChunkUtils
{ {
public: public:
// buffer offset util
static int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags);
// file chunk offset // file chunk offset
static int getOffset(int flags); static int getOffset(int flags);

View File

@@ -20,6 +20,10 @@ subject to the following restrictions:
#include <stdlib.h> #include <stdlib.h>
#include <stdio.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; using namespace bParse;
@@ -213,7 +217,8 @@ void bDNA::initCmpFlags(bDNA *memDNA)
// rebuild... // rebuild...
mCMPFlags[i] = FDF_STRUCT_NEQU; mCMPFlags[i] = FDF_STRUCT_NEQU;
#if 1 #ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY
if (curStruct[1] == oldStruct[1]) if (curStruct[1] == oldStruct[1])
{ {
// type len same ... // type len same ...

View File

@@ -19,12 +19,14 @@ subject to the following restrictions:
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "bDefines.h"
#include "LinearMath/btSerializer.h"
#define SIZEOFBLENDERHEADER 12 #define SIZEOFBLENDERHEADER 12
#define MAX_ARRAY_LENGTH 512 #define MAX_ARRAY_LENGTH 512
using namespace bParse; using namespace bParse;
//this define will force traversal of structures, to check backward (and forward) compatibility
//#define TEST_BACKWARD_FORWARD_COMPATIBILITY
int numallocs = 0; 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)) if (!mFileDNA->flagEqual(dataChunk.dna_nr))
#endif
{ {
// Ouch! need to rebuild the struct // Ouch! need to rebuild the struct
short *oldStruct,*curStruct; 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 ptrFile = mFileDNA->getPointerSize();
int ptrMem = mMemoryDNA->getPointerSize(); int ptrMem = mMemoryDNA->getPointerSize();
@@ -516,22 +515,52 @@ void bFile::swapPtr(char *dst, char *src)
if (!src && !dst) if (!src && !dst)
return; return;
if (ptrFile == ptrMem) if (ptrFile == ptrMem)
{
memcpy(dst, src, ptrMem); memcpy(dst, src, ptrMem);
}
else if (ptrMem==4 && ptrFile==8) else if (ptrMem==4 && ptrFile==8)
{ {
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); long64 longValue = *((long64*)src);
*((int*)dst) = (int)(longValue>>3); *((int*)dst) = (int)(longValue>>3);
} }
}
else if (ptrMem==8 && ptrFile==4) else if (ptrMem==8 && ptrFile==4)
{
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); *((long64*)dst)= *((int*)src);
}
}
else else
{ {
printf ("%d %d\n", ptrFile,ptrMem); printf ("%d %d\n", ptrFile,ptrMem);
assert(0 && "Invalid pointer len"); assert(0 && "Invalid pointer len");
} }
} }
// ----------------------------------------------------- // // ----------------------------------------------------- //
void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers) 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 // cast pointers
int ptrFile = mFileDNA->getPointerSize(); int ptrFile = mFileDNA->getPointerSize();
int ptrMem = mMemoryDNA->getPointerSize(); int ptrMem = mMemoryDNA->getPointerSize();
safeSwapPtr(strcData,data);
swapPtr(strcData, data);
if (fixupPointers) if (fixupPointers)
{ {
@@ -577,7 +605,7 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c
for (int a=0; a<arrayLen; a++) for (int a=0; a<arrayLen; a++)
{ {
swapPtr(cpc, cpo); safeSwapPtr(cpc, cpo);
m_pointerFixupArray.push_back(cpc); m_pointerFixupArray.push_back(cpc);
cpc += ptrMem; cpc += ptrMem;
cpo += ptrFile; cpo += ptrFile;
@@ -732,12 +760,12 @@ void bFile::resolvePointersMismatch()
{ {
if (ptrMem > ptrFile) if (ptrMem > ptrFile)
{ {
swapPtr((char*)&array[n2], (char*)&array[n]); safeSwapPtr((char*)&array[n2], (char*)&array[n]);
np = findLibPointer(array[n2]); np = findLibPointer(array[n2]);
} }
else if (ptrMem < ptrFile) else if (ptrMem < ptrFile)
{ {
swapPtr((char*)&array[n], (char*)&array[n2]); safeSwapPtr((char*)&array[n], (char*)&array[n2]);
np = findLibPointer(array[n]); np = findLibPointer(array[n]);
} }
else else
@@ -944,11 +972,7 @@ void bFile::resolvePointers(bool verboseDumpAllBlocks)
{ {
const bChunkInd& dataChunk = m_chunks.at(i); const bChunkInd& dataChunk = m_chunks.at(i);
#ifdef TEST_BACKWARD_FORWARD_COMPATIBILITY
if (1)
#else
if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr)) if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr))
#endif
{ {
//dataChunk.len //dataChunk.len
short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); 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 //eof

View File

@@ -65,9 +65,14 @@ namespace bParse {
bPtrMap mDataPointers; bPtrMap mDataPointers;
int mFlags; 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 parseHeader();
virtual void parseData() = 0; virtual void parseData() = 0;
@@ -76,7 +81,7 @@ namespace bParse {
void resolvePointersChunk(const bChunkInd& dataChunk, bool verboseDumpAllBlocks); void resolvePointersChunk(const bChunkInd& dataChunk, bool verboseDumpAllBlocks);
void resolvePointersStructRecursive(char *strcPtr, int old_dna, bool verboseDumpAllBlocks, int recursion); 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 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); void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers);

View File

@@ -120,7 +120,7 @@ void btBulletFile::parseData()
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
int seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
//dataPtr += ChunkUtils::getOffset(mFlags); //dataPtr += ChunkUtils::getOffset(mFlags);
char *dataPtrHead = 0; char *dataPtrHead = 0;
@@ -134,7 +134,7 @@ void btBulletFile::parseData()
if (dataChunk.code == SDNA) break; if (dataChunk.code == SDNA) break;
//if (dataChunk.code == DNA1) break; //if (dataChunk.code == DNA1) break;
// same as (BHEAD+DATA dependancy) // same as (BHEAD+DATA dependency)
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
if (dataChunk.dna_nr>=0) if (dataChunk.dna_nr>=0)
{ {
@@ -196,7 +196,7 @@ void btBulletFile::parseData()
// next please! // next please!
dataPtr += seek; dataPtr += seek;
seek = ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); seek = getNextBlock(&dataChunk, dataPtr, mFlags);
if (seek < 0) if (seek < 0)
break; break;
} }

View File

@@ -21,13 +21,8 @@ subject to the following restrictions:
#include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btAlignedObjectArray.h"
#include "bDefines.h" #include "bDefines.h"
#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J') #include "LinearMath/btSerializer.h"
#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')
namespace bParse { namespace bParse {

View File

@@ -263,11 +263,11 @@ int main(int argc,char** argv)
if (isBulletFile) if (isBulletFile)
{ {
btBulletFile f(memBuf,len); btBulletFile f(memBuf,len);
swap = f.getFlags() & FD_ENDIAN_SWAP; swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
} else } else
{ {
bBlenderFile f(memBuf,len); bBlenderFile f(memBuf,len);
swap = f.getFlags() & FD_ENDIAN_SWAP; swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
} }

View File

@@ -1302,7 +1302,7 @@ const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer
quantizedData->m_useQuantization = m_useQuantization; quantizedData->m_useQuantization = m_useQuantization;
quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size(); quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? &m_contiguousNodes[0] : 0); quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
if (quantizedData->m_contiguousNodesPtr) if (quantizedData->m_contiguousNodesPtr)
{ {
int sz = sizeof(btOptimizedBvhNodeData); int sz = sizeof(btOptimizedBvhNodeData);
@@ -1322,7 +1322,7 @@ const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer
quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size(); quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
// printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes); // printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? &m_quantizedContiguousNodes[0] : 0); quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
if (quantizedData->m_quantizedContiguousNodesPtr) if (quantizedData->m_quantizedContiguousNodesPtr)
{ {
int sz = sizeof(btQuantizedBvhNodeData); int sz = sizeof(btQuantizedBvhNodeData);
@@ -1345,7 +1345,7 @@ const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer
quantizedData->m_traversalMode = int(m_traversalMode); quantizedData->m_traversalMode = int(m_traversalMode);
quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size(); quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? &m_SubtreeHeaders[0] : 0); quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
if (quantizedData->m_subTreeInfoPtr) if (quantizedData->m_subTreeInfoPtr)
{ {
int sz = sizeof(btBvhSubtreeInfoData); int sz = sizeof(btBvhSubtreeInfoData);

View File

@@ -78,7 +78,7 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali
dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction; dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction;
dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold; dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold;
dataOut->m_broadphaseHandle = 0; dataOut->m_broadphaseHandle = 0;
dataOut->m_collisionShape = m_collisionShape; //@todo dataOut->m_collisionShape = serializer->getUniquePointer(m_collisionShape);
dataOut->m_rootCollisionShape = 0;//@todo dataOut->m_rootCollisionShape = 0;//@todo
dataOut->m_collisionFlags = m_collisionFlags; dataOut->m_collisionFlags = m_collisionFlags;
dataOut->m_islandTag1 = m_islandTag1; dataOut->m_islandTag1 = m_islandTag1;

View File

@@ -397,10 +397,10 @@ const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* se
{ {
#ifdef BT_USE_DOUBLE_PRECISION #ifdef BT_USE_DOUBLE_PRECISION
trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)m_bvh; trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh);
trimeshData->m_quantizedFloatBvh = 0; trimeshData->m_quantizedFloatBvh = 0;
#else #else
trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)m_bvh; trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh);
trimeshData->m_quantizedDoubleBvh= 0; trimeshData->m_quantizedDoubleBvh= 0;
#endif //BT_USE_DOUBLE_PRECISION #endif //BT_USE_DOUBLE_PRECISION
@@ -425,7 +425,7 @@ const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* se
trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk; trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk;
} else } else
{ {
trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)m_triangleInfoMap; trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)serializer->getUniquePointer(m_triangleInfoMap);
int sz = m_triangleInfoMap->calculateSerializeBufferSize(); int sz = m_triangleInfoMap->calculateSerializeBufferSize();
btChunk* chunk = serializer->allocate(sz,1); btChunk* chunk = serializer->allocate(sz,1);
const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer);

View File

@@ -299,12 +299,12 @@ const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serialize
{ {
btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes); btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes);
btCompoundShapeChildData* memPtr = (btCompoundShapeChildData*)chunk->m_oldPtr; btCompoundShapeChildData* memPtr = (btCompoundShapeChildData*)chunk->m_oldPtr;
shapeData->m_childShapePtr = memPtr; shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr);
for (int i=0;i<shapeData->m_numChildShapes;i++,memPtr++) for (int i=0;i<shapeData->m_numChildShapes;i++,memPtr++)
{ {
memPtr->m_childMargin = float(m_children[i].m_childMargin); memPtr->m_childMargin = float(m_children[i].m_childMargin);
memPtr->m_childShape = (btCollisionShapeData*)m_children[i].m_childShape; memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape);
//don't serialize shapes that already have been serialized //don't serialize shapes that already have been serialized
if (!serializer->findPointer(memPtr->m_childShape)) if (!serializer->findPointer(memPtr->m_childShape))
{ {

View File

@@ -197,9 +197,9 @@ const char* btConvexHullShape::serialize(void* dataBuffer, btSerializer* seriali
shapeData->m_numUnscaledPoints = numElem; shapeData->m_numUnscaledPoints = numElem;
#ifdef BT_USE_DOUBLE_PRECISION #ifdef BT_USE_DOUBLE_PRECISION
shapeData->m_unscaledPointsFloatPtr = 0; shapeData->m_unscaledPointsFloatPtr = 0;
shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)&m_unscaledPoints[0]: 0; shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0;
#else #else
shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)&m_unscaledPoints[0]: 0; shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0;
shapeData->m_unscaledPointsDoublePtr = 0; shapeData->m_unscaledPointsDoublePtr = 0;
#endif #endif

View File

@@ -146,7 +146,7 @@ const char* btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serial
btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer); btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
int numElem = m_localPositionArray.size(); int numElem = m_localPositionArray.size();
shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)&m_localPositionArray[0]: 0; shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]): 0;
shapeData->m_localPositionArraySize = numElem; shapeData->m_localPositionArraySize = numElem;
if (numElem) if (numElem)

View File

@@ -198,7 +198,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
{ {
btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts); btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr; btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
trimeshData->m_meshPartsPtr = memPtr; trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
// int numtotalphysicsverts = 0; // int numtotalphysicsverts = 0;
@@ -235,7 +235,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
{ {
btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices); btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr; btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
memPtr->m_indices32 = tmpIndices; memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
for (gfxindex=0;gfxindex<numtriangles;gfxindex++) for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{ {
unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride); unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
@@ -253,7 +253,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
{ {
btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles); btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr; btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
memPtr->m_3indices16 = tmpIndices; memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
for (gfxindex=0;gfxindex<numtriangles;gfxindex++) for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{ {
unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride); unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
@@ -282,7 +282,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
{ {
btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts); btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr; btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
memPtr->m_vertices3f = tmpVertices; memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
for (int i=0;i<numverts;i++) for (int i=0;i<numverts;i++)
{ {
graphicsbase = (float*)(vertexbase+i*stride); graphicsbase = (float*)(vertexbase+i*stride);
@@ -301,7 +301,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
{ {
btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts); btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr; btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
memPtr->m_vertices3d = tmpVertices; memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
for (int i=0;i<numverts;i++) for (int i=0;i<numverts;i++)
{ {
double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double

View File

@@ -127,7 +127,8 @@ SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btS
tmapData->m_zeroAreaThreshold = m_zeroAreaThreshold; tmapData->m_zeroAreaThreshold = m_zeroAreaThreshold;
tmapData->m_hashTableSize = m_hashTable.size(); tmapData->m_hashTableSize = m_hashTable.size();
tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)&m_hashTable[0] : 0;
tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0;
if (tmapData->m_hashTablePtr) if (tmapData->m_hashTablePtr)
{ {
//serialize an int buffer //serialize an int buffer
@@ -144,7 +145,7 @@ SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btS
} }
tmapData->m_nextSize = m_next.size(); tmapData->m_nextSize = m_next.size();
tmapData->m_nextPtr = tmapData->m_nextSize? (int*)&m_next[0]: 0; tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0;
if (tmapData->m_nextPtr) if (tmapData->m_nextPtr)
{ {
int sz = sizeof(int); int sz = sizeof(int);
@@ -159,7 +160,7 @@ SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btS
} }
tmapData->m_numValues = m_valueArray.size(); tmapData->m_numValues = m_valueArray.size();
tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)&m_valueArray[0]: 0; tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0;
if (tmapData->m_valueArrayPtr) if (tmapData->m_valueArrayPtr)
{ {
int sz = sizeof(btTriangleInfoData); int sz = sizeof(btTriangleInfoData);
@@ -177,7 +178,7 @@ SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btS
} }
tmapData->m_numKeys = m_keyArray.size(); tmapData->m_numKeys = m_keyArray.size();
tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)&m_keyArray[0] : 0; tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)serializer->getUniquePointer((void*)&m_keyArray[0]) : 0;
if (tmapData->m_keyArrayPtr) if (tmapData->m_keyArrayPtr)
{ {
int sz = sizeof(int); int sz = sizeof(int);

View File

@@ -103,8 +103,8 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali
{ {
btTypedConstraintData* tcd = (btTypedConstraintData*) dataBuffer; btTypedConstraintData* tcd = (btTypedConstraintData*) dataBuffer;
tcd->m_rbA = (btRigidBodyData*)&m_rbA; tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
tcd->m_rbB = (btRigidBodyData*)&m_rbB; tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
tcd->m_name = (char*) serializer->findNameForPointer(this); tcd->m_name = (char*) serializer->findNameForPointer(this);
if (tcd->m_name) if (tcd->m_name)
{ {

View File

@@ -83,6 +83,8 @@ public:
virtual void* findPointer(void* oldPtr) = 0; virtual void* findPointer(void* oldPtr) = 0;
virtual void* getUniquePointer(void*oldPtr) = 0;
virtual void startSerialization() = 0; virtual void startSerialization() = 0;
virtual void finishSerialization() = 0; virtual void finishSerialization() = 0;
@@ -97,6 +99,7 @@ public:
virtual void setSerializationFlags(int flags) = 0; virtual void setSerializationFlags(int flags) = 0;
}; };
@@ -118,6 +121,15 @@ public:
#define BT_ARRAY_CODE MAKE_ID('A','R','A','Y') #define BT_ARRAY_CODE MAKE_ID('A','R','A','Y')
struct btPointerUid
{
union
{
void* m_ptr;
int m_uniqueIds[2];
};
};
class btDefaultSerializer : public btSerializer class btDefaultSerializer : public btSerializer
{ {
@@ -134,6 +146,8 @@ class btDefaultSerializer : public btSerializer
btHashMap<btHashPtr,const char*> m_nameMap; btHashMap<btHashPtr,const char*> m_nameMap;
btHashMap<btHashPtr,btPointerUid> m_uniquePointers;
int m_uniqueIdGenerator;
int m_totalSize; int m_totalSize;
unsigned char* m_buffer; unsigned char* m_buffer;
@@ -158,6 +172,8 @@ protected:
void writeDNA() void writeDNA()
{ {
unsigned char* dnaTarget = m_buffer+m_currentSize; unsigned char* dnaTarget = m_buffer+m_currentSize;
@@ -403,6 +419,8 @@ public:
virtual void startSerialization() virtual void startSerialization()
{ {
m_uniqueIdGenerator= 1;
m_currentSize = BT_HEADER_LENGTH; m_currentSize = BT_HEADER_LENGTH;
#ifdef BT_USE_DOUBLE_PRECISION #ifdef BT_USE_DOUBLE_PRECISION
@@ -450,8 +468,25 @@ public:
mTypeLookup.clear(); mTypeLookup.clear();
m_chunkP.clear(); m_chunkP.clear();
m_nameMap.clear(); m_nameMap.clear();
m_uniquePointers.clear();
} }
virtual void* getUniquePointer(void*oldPtr)
{
btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
if (uptr)
{
return uptr->m_ptr;
}
m_uniqueIdGenerator++;
btPointerUid uid;
uid.m_uniqueIds[0] = m_uniqueIdGenerator;
uid.m_uniqueIds[1] = m_uniqueIdGenerator;
m_uniquePointers.insert(oldPtr,uid);
return uid.m_ptr;
}
virtual const unsigned char* getBufferPointer() const virtual const unsigned char* getBufferPointer() const
{ {
@@ -473,8 +508,11 @@ public:
chunk->m_dna_nr = getReverseType(structType); chunk->m_dna_nr = getReverseType(structType);
chunk->m_chunkCode = chunkCode; chunk->m_chunkCode = chunkCode;
m_chunkP.insert(oldPtr,chunk->m_oldPtr);
chunk->m_oldPtr = oldPtr; void* uniquePtr = getUniquePointer(oldPtr);
m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr);
chunk->m_oldPtr = uniquePtr;//oldPtr;
} }