909 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			909 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose,
							 | 
						||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely,
							 | 
						||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
							 | 
						||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BT_SERIALIZER_H
							 | 
						||
| 
								 | 
							
								#define BT_SERIALIZER_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
							 | 
						||
| 
								 | 
							
								#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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual int getNumChunks() const = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual const btChunk* getChunk(int chunkIndex) const = 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_MULTIBODY_CODE       BT_MAKE_ID('M','B','D','Y')
							 | 
						||
| 
								 | 
							
								#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];
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btBulletSerializedArrays
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btBulletSerializedArrays()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btQuantizedBvhDoubleData*>	m_bvhsDouble;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btQuantizedBvhFloatData*>	m_bvhsFloat;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btCollisionShapeData*> m_colShapeData;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btDynamicsWorldDoubleData*> m_dynamicWorldInfoDataDouble;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btDynamicsWorldFloatData*> m_dynamicWorldInfoDataFloat;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btRigidBodyDoubleData*> m_rigidBodyDataDouble;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btRigidBodyFloatData*> m_rigidBodyDataFloat;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btCollisionObjectDoubleData*> m_collisionObjectDataDouble;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btCollisionObjectFloatData*> m_collisionObjectDataFloat;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btTypedConstraintFloatData*> m_constraintDataFloat;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btTypedConstraintDoubleData*> m_constraintDataDouble;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btTypedConstraintData*> m_constraintData;//for backwards compatibility
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btSoftBodyFloatData*> m_softBodyFloatData;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<struct btSoftBodyDoubleData*> m_softBodyDoubleData;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///The btDefaultSerializer is the main Bullet serialization class.
							 | 
						||
| 
								 | 
							
								///The constructor takes an optional argument for backwards compatibility, it is recommended to leave this empty/zero.
							 | 
						||
| 
								 | 
							
								class btDefaultSerializer	:	public btSerializer
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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;
							 | 
						||
| 
								 | 
							
									bool                m_ownsBuffer;
							 | 
						||
| 
								 | 
							
									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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										virtual 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)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											///was already initialized
							 | 
						||
| 
								 | 
							
											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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/*
							 | 
						||
| 
								 | 
							
												SDNA (4 bytes) (magic number)
							 | 
						||
| 
								 | 
							
												NAME (4 bytes)
							 | 
						||
| 
								 | 
							
												<nr> (4 bytes) amount of names (int)
							 | 
						||
| 
								 | 
							
												<string>
							 | 
						||
| 
								 | 
							
												<string>
							 | 
						||
| 
								 | 
							
											*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (strncmp((const char*)m_dna, "SDNA", 4)==0)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												// skip ++ NAME
							 | 
						||
| 
								 | 
							
												intPtr++; intPtr++;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// Parse names
							 | 
						||
| 
								 | 
							
											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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/*
							 | 
						||
| 
								 | 
							
												TYPE (4 bytes)
							 | 
						||
| 
								 | 
							
												<nr> amount of types (int)
							 | 
						||
| 
								 | 
							
												<string>
							 | 
						||
| 
								 | 
							
												<string>
							 | 
						||
| 
								 | 
							
											*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/*
							 | 
						||
| 
								 | 
							
												TLEN (4 bytes)
							 | 
						||
| 
								 | 
							
												<len> (short) the lengths of types
							 | 
						||
| 
								 | 
							
												<len>
							 | 
						||
| 
								 | 
							
											*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// Parse type lens
							 | 
						||
| 
								 | 
							
											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++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/*
							 | 
						||
| 
								 | 
							
												STRC (4 bytes)
							 | 
						||
| 
								 | 
							
												<nr> amount of structs (int)
							 | 
						||
| 
								 | 
							
												<typenr>
							 | 
						||
| 
								 | 
							
												<nr_of_elems>
							 | 
						||
| 
								 | 
							
												<typenr>
							 | 
						||
| 
								 | 
							
												<namenr>
							 | 
						||
| 
								 | 
							
												<typenr>
							 | 
						||
| 
								 | 
							
												<namenr>
							 | 
						||
| 
								 | 
							
											*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											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;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// build reverse lookups
							 | 
						||
| 
								 | 
							
											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:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btHashMap<btHashPtr,void*> m_skipPointers;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										btDefaultSerializer(int totalSize=0, unsigned char*	buffer=0)
							 | 
						||
| 
								 | 
							
											:m_uniqueIdGenerator(0),
							 | 
						||
| 
								 | 
							
											m_totalSize(totalSize),
							 | 
						||
| 
								 | 
							
											m_currentSize(0),
							 | 
						||
| 
								 | 
							
											m_dna(0),
							 | 
						||
| 
								 | 
							
											m_dnaLength(0),
							 | 
						||
| 
								 | 
							
											m_serializationFlags(0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
										    if (buffer==0)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                m_buffer = m_totalSize?(unsigned char*)btAlignedAlloc(totalSize,16):0;
							 | 
						||
| 
								 | 
							
								                m_ownsBuffer = true;
							 | 
						||
| 
								 | 
							
								            } else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                m_buffer = buffer;
							 | 
						||
| 
								 | 
							
								                m_ownsBuffer = false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											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 //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
							 | 
						||
| 
								 | 
							
											if (VOID_IS_8)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
							 | 
						||
| 
								 | 
							
											} else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										virtual ~btDefaultSerializer()
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if (m_buffer && m_ownsBuffer)
							 | 
						||
| 
								 | 
							
												btAlignedFree(m_buffer);
							 | 
						||
| 
								 | 
							
											if (m_dna)
							 | 
						||
| 
								 | 
							
												btAlignedFree(m_dna);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										static int getMemoryDnaSizeInBytes()
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const bool VOID_IS_8 = ((sizeof(void*) == 8));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (VOID_IS_8)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												return sBulletDNAlen64;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return sBulletDNAlen;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										static const char* getMemoryDna()
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const bool VOID_IS_8 = ((sizeof(void*) == 8));
							 | 
						||
| 
								 | 
							
											if (VOID_IS_8)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												return (const char*)sBulletDNAstr64;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return (const char*)sBulletDNAstr;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										void	insertHeader()
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											writeHeader(m_buffer);
							 | 
						||
| 
								 | 
							
											m_currentSize += BT_HEADER_LENGTH;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										void	writeHeader(unsigned char* buffer) const
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef  BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
											memcpy(buffer, "BULLETd", 7);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
											memcpy(buffer, "BULLETf", 7);
							 | 
						||
| 
								 | 
							
								#endif //BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											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] = '7';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										virtual	void	startSerialization()
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_uniqueIdGenerator= 1;
							 | 
						||
| 
								 | 
							
											if (m_totalSize)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												unsigned char* buffer = internalAlloc(BT_HEADER_LENGTH);
							 | 
						||
| 
								 | 
							
												writeHeader(buffer);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										virtual	void	finishSerialization()
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											writeDNA();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//if we didn't pre-allocate a buffer, we need to create a contiguous buffer now
							 | 
						||
| 
								 | 
							
											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_skipPointers.clear();
							 | 
						||
| 
								 | 
							
											m_chunkP.clear();
							 | 
						||
| 
								 | 
							
											m_nameMap.clear();
							 | 
						||
| 
								 | 
							
											m_uniquePointers.clear();
							 | 
						||
| 
								 | 
							
											m_chunkPtrs.clear();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										virtual	void*	getUniquePointer(void*oldPtr)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btAssert(m_uniqueIdGenerator >= 0);
							 | 
						||
| 
								 | 
							
											if (!oldPtr)
							 | 
						||
| 
								 | 
							
												return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
							 | 
						||
| 
								 | 
							
											if (uptr)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												return uptr->m_ptr;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											void** ptr2 = m_skipPointers[oldPtr];
							 | 
						||
| 
								 | 
							
								            if (ptr2)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												return 0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											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);
							 | 
						||
| 
								 | 
							
											chunk->m_oldPtr = uniquePtr;//oldPtr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										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)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												//don't serialize name twice
							 | 
						||
| 
								 | 
							
												if (findPointer((void*)name))
							 | 
						||
| 
								 | 
							
													return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												int len = btStrLen(name);
							 | 
						||
| 
								 | 
							
												if (len)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													int newLen = len+1;
							 | 
						||
| 
								 | 
							
													int padding = ((newLen+3)&~3)-newLen;
							 | 
						||
| 
								 | 
							
													newLen += padding;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													//serialize name string now
							 | 
						||
| 
								 | 
							
													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;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										int getNumChunks() const
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											return m_chunkPtrs.size();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const btChunk* getChunk(int chunkIndex) const
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											return m_chunkPtrs[chunkIndex];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///In general it is best to use btDefaultSerializer,
							 | 
						||
| 
								 | 
							
								///in particular when writing the data to disk or sending it over the network.
							 | 
						||
| 
								 | 
							
								///The btInMemorySerializer is experimental and only suitable in a few cases.
							 | 
						||
| 
								 | 
							
								///The btInMemorySerializer takes a shortcut and can be useful to create a deep-copy
							 | 
						||
| 
								 | 
							
								///of objects. There will be a demo on how to use the btInMemorySerializer.
							 | 
						||
| 
								 | 
							
								#ifdef ENABLE_INMEMORY_SERIALIZER
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btInMemorySerializer : public btDefaultSerializer
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    btHashMap<btHashPtr,btChunk*> m_uid2ChunkPtr;
							 | 
						||
| 
								 | 
							
								    btHashMap<btHashPtr,void*> m_orgPtr2UniqueDataPtr;
							 | 
						||
| 
								 | 
							
								    btHashMap<btHashString,const void*> m_names2Ptr;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    btBulletSerializedArrays    m_arrays;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    btInMemorySerializer(int totalSize=0, unsigned char*	buffer=0)
							 | 
						||
| 
								 | 
							
								    :btDefaultSerializer(totalSize,buffer)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void startSerialization()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_uid2ChunkPtr.clear();
							 | 
						||
| 
								 | 
							
								        //todo: m_arrays.clear();
							 | 
						||
| 
								 | 
							
								        btDefaultSerializer::startSerialization();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    btChunk* findChunkFromUniquePointer(void* uniquePointer)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        btChunk** chkPtr = m_uid2ChunkPtr[uniquePointer];
							 | 
						||
| 
								 | 
							
								        if (chkPtr)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return *chkPtr;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual	void	registerNameForPointer(const void* ptr, const char* name)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								       btDefaultSerializer::registerNameForPointer(ptr,name);
							 | 
						||
| 
								 | 
							
								       m_names2Ptr.insert(name,ptr);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void finishSerialization()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void* getUniquePointer(void*oldPtr)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (oldPtr==0)
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // void* uniquePtr = getUniquePointer(oldPtr);
							 | 
						||
| 
								 | 
							
								        btChunk* chunk = findChunkFromUniquePointer(oldPtr);
							 | 
						||
| 
								 | 
							
								        if (chunk)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return chunk->m_oldPtr;
							 | 
						||
| 
								 | 
							
								        } else
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            const char* n = (const char*) oldPtr;
							 | 
						||
| 
								 | 
							
								            const void** ptr = m_names2Ptr[n];
							 | 
						||
| 
								 | 
							
								            if (ptr)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return oldPtr;
							 | 
						||
| 
								 | 
							
								            } else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								            		void** ptr2 = m_skipPointers[oldPtr];
							 | 
						||
| 
								 | 
							
								            		if (ptr2)
							 | 
						||
| 
								 | 
							
																{
							 | 
						||
| 
								 | 
							
																	return 0;
							 | 
						||
| 
								 | 
							
																} else
							 | 
						||
| 
								 | 
							
																{
							 | 
						||
| 
								 | 
							
																	//If this assert hit, serialization happened in the wrong order
							 | 
						||
| 
								 | 
							
																	// 'getUniquePointer'
							 | 
						||
| 
								 | 
							
																	btAssert(0);
							 | 
						||
| 
								 | 
							
																}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
												return oldPtr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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,oldPtr);//chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
								        // chunk->m_oldPtr = uniquePtr;//oldPtr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void* uid = findPointer(oldPtr);
							 | 
						||
| 
								 | 
							
								        m_uid2ChunkPtr.insert(uid,chunk);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        switch (chunk->m_chunkCode)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
											case BT_SOFTBODY_CODE:
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
									#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													m_arrays.m_softBodyDoubleData.push_back((btSoftBodyDoubleData*) chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
													m_arrays.m_softBodyFloatData.push_back((btSoftBodyFloatData*) chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case BT_COLLISIONOBJECT_CODE:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
									#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													m_arrays.m_collisionObjectDataDouble.push_back((btCollisionObjectDoubleData*)chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#else//BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													m_arrays.m_collisionObjectDataFloat.push_back((btCollisionObjectFloatData*)chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#endif //BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case BT_RIGIDBODY_CODE:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
									#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													m_arrays.m_rigidBodyDataDouble.push_back((btRigidBodyDoubleData*)chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
													m_arrays.m_rigidBodyDataFloat.push_back((btRigidBodyFloatData*)chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#endif//BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												};
							 | 
						||
| 
								 | 
							
											case BT_CONSTRAINT_CODE:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
									#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													m_arrays.m_constraintDataDouble.push_back((btTypedConstraintDoubleData*)chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
													m_arrays.m_constraintDataFloat.push_back((btTypedConstraintFloatData*)chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case BT_QUANTIZED_BVH_CODE:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
									#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
													m_arrays.m_bvhsDouble.push_back((btQuantizedBvhDoubleData*) chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
													m_arrays.m_bvhsFloat.push_back((btQuantizedBvhFloatData*) chunk->m_oldPtr);
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case BT_SHAPE_CODE:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													btCollisionShapeData* shapeData = (btCollisionShapeData*) chunk->m_oldPtr;
							 | 
						||
| 
								 | 
							
													m_arrays.m_colShapeData.push_back(shapeData);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case BT_TRIANLGE_INFO_MAP:
							 | 
						||
| 
								 | 
							
											case BT_ARRAY_CODE:
							 | 
						||
| 
								 | 
							
											case BT_SBMATERIAL_CODE:
							 | 
						||
| 
								 | 
							
											case BT_SBNODE_CODE:
							 | 
						||
| 
								 | 
							
											case BT_DYNAMICSWORLD_CODE:
							 | 
						||
| 
								 | 
							
											case BT_DNA_CODE:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int getNumChunks() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_uid2ChunkPtr.size();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const btChunk* getChunk(int chunkIndex) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return *m_uid2ChunkPtr.getAtIndex(chunkIndex);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#endif //ENABLE_INMEMORY_SERIALIZER
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BT_SERIALIZER_H
							 | 
						||
| 
								 | 
							
								
							 |