123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- #ifndef BT_SERIALIZER_H
- #define BT_SERIALIZER_H
- #include "btScalar.h"
- #include "btHashMap.h"
- #if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
- #include <memory.h>
- #endif
- #include <string.h>
- extern char sBulletDNAstr[];
- extern int sBulletDNAlen;
- extern char sBulletDNAstr64[];
- extern int sBulletDNAlen64;
- SIMD_FORCE_INLINE int btStrLen(const char* str)
- {
- if (!str)
- return(0);
- int len = 0;
-
- while (*str != 0)
- {
- str++;
- len++;
- }
- return len;
- }
- class btChunk
- {
- public:
- int m_chunkCode;
- int m_length;
- void *m_oldPtr;
- int m_dna_nr;
- int m_number;
- };
- enum btSerializationFlags
- {
- BT_SERIALIZE_NO_BVH = 1,
- BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2,
- BT_SERIALIZE_NO_DUPLICATE_ASSERT = 4
- };
- class btSerializer
- {
- public:
- virtual ~btSerializer() {}
- virtual const unsigned char* getBufferPointer() const = 0;
- virtual int getCurrentBufferSize() const = 0;
- virtual btChunk* allocate(size_t size, int numElements) = 0;
- virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0;
- virtual void* findPointer(void* oldPtr) = 0;
- virtual void* getUniquePointer(void*oldPtr) = 0;
- virtual void startSerialization() = 0;
-
- virtual void finishSerialization() = 0;
- virtual const char* findNameForPointer(const void* ptr) const = 0;
- virtual void registerNameForPointer(const void* ptr, const char* name) = 0;
- virtual void serializeName(const char* ptr) = 0;
- virtual int getSerializationFlags() const = 0;
- virtual void setSerializationFlags(int flags) = 0;
- };
- #define BT_HEADER_LENGTH 12
- #if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
- # define BT_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
- #else
- # define BT_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
- #endif
- #define BT_SOFTBODY_CODE BT_MAKE_ID('S','B','D','Y')
- #define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C','O','B','J')
- #define BT_RIGIDBODY_CODE BT_MAKE_ID('R','B','D','Y')
- #define BT_CONSTRAINT_CODE BT_MAKE_ID('C','O','N','S')
- #define BT_BOXSHAPE_CODE BT_MAKE_ID('B','O','X','S')
- #define BT_QUANTIZED_BVH_CODE BT_MAKE_ID('Q','B','V','H')
- #define BT_TRIANLGE_INFO_MAP BT_MAKE_ID('T','M','A','P')
- #define BT_SHAPE_CODE BT_MAKE_ID('S','H','A','P')
- #define BT_ARRAY_CODE BT_MAKE_ID('A','R','A','Y')
- #define BT_SBMATERIAL_CODE BT_MAKE_ID('S','B','M','T')
- #define BT_SBNODE_CODE BT_MAKE_ID('S','B','N','D')
- #define BT_DYNAMICSWORLD_CODE BT_MAKE_ID('D','W','L','D')
- #define BT_DNA_CODE BT_MAKE_ID('D','N','A','1')
- struct btPointerUid
- {
- union
- {
- void* m_ptr;
- int m_uniqueIds[2];
- };
- };
- class btDefaultSerializer : public btSerializer
- {
- btAlignedObjectArray<char*> mTypes;
- btAlignedObjectArray<short*> mStructs;
- btAlignedObjectArray<short> mTlens;
- btHashMap<btHashInt, int> mStructReverse;
- btHashMap<btHashString,int> mTypeLookup;
-
- btHashMap<btHashPtr,void*> m_chunkP;
-
- btHashMap<btHashPtr,const char*> m_nameMap;
- btHashMap<btHashPtr,btPointerUid> m_uniquePointers;
- int m_uniqueIdGenerator;
- int m_totalSize;
- unsigned char* m_buffer;
- int m_currentSize;
- void* m_dna;
- int m_dnaLength;
- int m_serializationFlags;
- btAlignedObjectArray<btChunk*> m_chunkPtrs;
-
- protected:
- virtual void* findPointer(void* oldPtr)
- {
- void** ptr = m_chunkP.find(oldPtr);
- if (ptr && *ptr)
- return *ptr;
- return 0;
- }
-
- void writeDNA()
- {
- btChunk* dnaChunk = allocate(m_dnaLength,1);
- memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength);
- finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna);
- }
- int getReverseType(const char *type) const
- {
- btHashString key(type);
- const int* valuePtr = mTypeLookup.find(key);
- if (valuePtr)
- return *valuePtr;
-
- return -1;
- }
- void initDNA(const char* bdnaOrg,int dnalen)
- {
-
- if (m_dna)
- return;
- int littleEndian= 1;
- littleEndian= ((char*)&littleEndian)[0];
-
- m_dna = btAlignedAlloc(dnalen,16);
- memcpy(m_dna,bdnaOrg,dnalen);
- m_dnaLength = dnalen;
- int *intPtr=0;
- short *shtPtr=0;
- char *cp = 0;int dataLen =0;
- intPtr = (int*)m_dna;
-
- if (strncmp((const char*)m_dna, "SDNA", 4)==0)
- {
-
- intPtr++; intPtr++;
- }
-
- if (!littleEndian)
- *intPtr = btSwapEndian(*intPtr);
-
- dataLen = *intPtr;
-
- intPtr++;
- cp = (char*)intPtr;
- int i;
- for ( i=0; i<dataLen; i++)
- {
-
- while (*cp)cp++;
- cp++;
- }
- cp = btAlignPointer(cp,4);
-
- intPtr = (int*)cp;
- btAssert(strncmp(cp, "TYPE", 4)==0); intPtr++;
- if (!littleEndian)
- *intPtr = btSwapEndian(*intPtr);
-
- dataLen = *intPtr;
- intPtr++;
-
- cp = (char*)intPtr;
- for (i=0; i<dataLen; i++)
- {
- mTypes.push_back(cp);
- while (*cp)cp++;
- cp++;
- }
- cp = btAlignPointer(cp,4);
-
-
- intPtr = (int*)cp;
- btAssert(strncmp(cp, "TLEN", 4)==0); intPtr++;
- dataLen = (int)mTypes.size();
- shtPtr = (short*)intPtr;
- for (i=0; i<dataLen; i++, shtPtr++)
- {
- if (!littleEndian)
- shtPtr[0] = btSwapEndian(shtPtr[0]);
- mTlens.push_back(shtPtr[0]);
- }
- if (dataLen & 1) shtPtr++;
-
- intPtr = (int*)shtPtr;
- cp = (char*)intPtr;
- btAssert(strncmp(cp, "STRC", 4)==0); intPtr++;
- if (!littleEndian)
- *intPtr = btSwapEndian(*intPtr);
- dataLen = *intPtr ;
- intPtr++;
- shtPtr = (short*)intPtr;
- for (i=0; i<dataLen; i++)
- {
- mStructs.push_back (shtPtr);
-
- if (!littleEndian)
- {
- shtPtr[0]= btSwapEndian(shtPtr[0]);
- shtPtr[1]= btSwapEndian(shtPtr[1]);
- int len = shtPtr[1];
- shtPtr+= 2;
- for (int a=0; a<len; a++, shtPtr+=2)
- {
- shtPtr[0]= btSwapEndian(shtPtr[0]);
- shtPtr[1]= btSwapEndian(shtPtr[1]);
- }
- } else
- {
- shtPtr+= (2*shtPtr[1])+2;
- }
- }
-
- for (i=0; i<(int)mStructs.size(); i++)
- {
- short *strc = mStructs.at(i);
- mStructReverse.insert(strc[0], i);
- mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
- }
- }
- public:
-
-
- btDefaultSerializer(int totalSize=0)
- :m_totalSize(totalSize),
- m_currentSize(0),
- m_dna(0),
- m_dnaLength(0),
- m_serializationFlags(0)
- {
- m_buffer = m_totalSize?(unsigned char*)btAlignedAlloc(totalSize,16):0;
-
- const bool VOID_IS_8 = ((sizeof(void*)==8));
- #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
- if (VOID_IS_8)
- {
- #if _WIN64
- initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
- #else
- btAssert(0);
- #endif
- } else
- {
- #ifndef _WIN64
- initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
- #else
- btAssert(0);
- #endif
- }
-
- #else
- if (VOID_IS_8)
- {
- initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
- } else
- {
- initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
- }
- #endif
-
- }
- virtual ~btDefaultSerializer()
- {
- if (m_buffer)
- btAlignedFree(m_buffer);
- if (m_dna)
- btAlignedFree(m_dna);
- }
- void writeHeader(unsigned char* buffer) const
- {
-
- #ifdef BT_USE_DOUBLE_PRECISION
- memcpy(buffer, "BULLETd", 7);
- #else
- memcpy(buffer, "BULLETf", 7);
- #endif
-
- int littleEndian= 1;
- littleEndian= ((char*)&littleEndian)[0];
- if (sizeof(void*)==8)
- {
- buffer[7] = '-';
- } else
- {
- buffer[7] = '_';
- }
- if (littleEndian)
- {
- buffer[8]='v';
- } else
- {
- buffer[8]='V';
- }
- buffer[9] = '2';
- buffer[10] = '8';
- buffer[11] = '2';
- }
- virtual void startSerialization()
- {
- m_uniqueIdGenerator= 1;
- if (m_totalSize)
- {
- unsigned char* buffer = internalAlloc(BT_HEADER_LENGTH);
- writeHeader(buffer);
- }
-
- }
- virtual void finishSerialization()
- {
- writeDNA();
-
- int mysize = 0;
- if (!m_totalSize)
- {
- if (m_buffer)
- btAlignedFree(m_buffer);
- m_currentSize += BT_HEADER_LENGTH;
- m_buffer = (unsigned char*)btAlignedAlloc(m_currentSize,16);
- unsigned char* currentPtr = m_buffer;
- writeHeader(m_buffer);
- currentPtr += BT_HEADER_LENGTH;
- mysize+=BT_HEADER_LENGTH;
- for (int i=0;i< m_chunkPtrs.size();i++)
- {
- int curLength = sizeof(btChunk)+m_chunkPtrs[i]->m_length;
- memcpy(currentPtr,m_chunkPtrs[i], curLength);
- btAlignedFree(m_chunkPtrs[i]);
- currentPtr+=curLength;
- mysize+=curLength;
- }
- }
- mTypes.clear();
- mStructs.clear();
- mTlens.clear();
- mStructReverse.clear();
- mTypeLookup.clear();
- m_chunkP.clear();
- m_nameMap.clear();
- m_uniquePointers.clear();
- m_chunkPtrs.clear();
- }
- virtual void* getUniquePointer(void*oldPtr)
- {
- if (!oldPtr)
- return 0;
- 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
- {
- return m_buffer;
- }
- virtual int getCurrentBufferSize() const
- {
- return m_currentSize;
- }
- virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
- {
- if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
- {
- btAssert(!findPointer(oldPtr));
- }
- chunk->m_dna_nr = getReverseType(structType);
-
- chunk->m_chunkCode = chunkCode;
-
- void* uniquePtr = getUniquePointer(oldPtr);
-
- m_chunkP.insert(oldPtr,uniquePtr);
- chunk->m_oldPtr = uniquePtr;
-
- }
-
- virtual unsigned char* internalAlloc(size_t size)
- {
- unsigned char* ptr = 0;
- if (m_totalSize)
- {
- ptr = m_buffer+m_currentSize;
- m_currentSize += int(size);
- btAssert(m_currentSize<m_totalSize);
- } else
- {
- ptr = (unsigned char*)btAlignedAlloc(size,16);
- m_currentSize += int(size);
- }
- return ptr;
- }
-
- virtual btChunk* allocate(size_t size, int numElements)
- {
- unsigned char* ptr = internalAlloc(int(size)*numElements+sizeof(btChunk));
- unsigned char* data = ptr + sizeof(btChunk);
-
- btChunk* chunk = (btChunk*)ptr;
- chunk->m_chunkCode = 0;
- chunk->m_oldPtr = data;
- chunk->m_length = int(size)*numElements;
- chunk->m_number = numElements;
-
- m_chunkPtrs.push_back(chunk);
-
- return chunk;
- }
- virtual const char* findNameForPointer(const void* ptr) const
- {
- const char*const * namePtr = m_nameMap.find(ptr);
- if (namePtr && *namePtr)
- return *namePtr;
- return 0;
- }
- virtual void registerNameForPointer(const void* ptr, const char* name)
- {
- m_nameMap.insert(ptr,name);
- }
- virtual void serializeName(const char* name)
- {
- if (name)
- {
-
- if (findPointer((void*)name))
- return;
- int len = btStrLen(name);
- if (len)
- {
- int newLen = len+1;
- int padding = ((newLen+3)&~3)-newLen;
- newLen += padding;
-
- btChunk* chunk = allocate(sizeof(char),newLen);
- char* destinationName = (char*)chunk->m_oldPtr;
- for (int i=0;i<len;i++)
- {
- destinationName[i] = name[i];
- }
- destinationName[len] = 0;
- finalizeChunk(chunk,"char",BT_ARRAY_CODE,(void*)name);
- }
- }
- }
- virtual int getSerializationFlags() const
- {
- return m_serializationFlags;
- }
- virtual void setSerializationFlags(int flags)
- {
- m_serializationFlags = flags;
- }
- };
- #endif
|