• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 #ifndef BT_SERIALIZER_H
17 #define BT_SERIALIZER_H
18 
19 #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
20 #include "btHashMap.h"
21 
22 #if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
23 #include <memory.h>
24 #endif
25 #include <string.h>
26 
27 
28 
29 ///only the 32bit versions for now
30 extern char sBulletDNAstr[];
31 extern int sBulletDNAlen;
32 extern char sBulletDNAstr64[];
33 extern int sBulletDNAlen64;
34 
btStrLen(const char * str)35 SIMD_FORCE_INLINE	int btStrLen(const char* str)
36 {
37     if (!str)
38 		return(0);
39 	int len = 0;
40 
41 	while (*str != 0)
42 	{
43         str++;
44         len++;
45     }
46 
47     return len;
48 }
49 
50 
51 class btChunk
52 {
53 public:
54 	int		m_chunkCode;
55 	int		m_length;
56 	void	*m_oldPtr;
57 	int		m_dna_nr;
58 	int		m_number;
59 };
60 
61 enum	btSerializationFlags
62 {
63 	BT_SERIALIZE_NO_BVH = 1,
64 	BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2,
65 	BT_SERIALIZE_NO_DUPLICATE_ASSERT = 4
66 };
67 
68 class	btSerializer
69 {
70 
71 public:
72 
~btSerializer()73 	virtual ~btSerializer() {}
74 
75 	virtual	const unsigned char*		getBufferPointer() const = 0;
76 
77 	virtual	int		getCurrentBufferSize() const = 0;
78 
79 	virtual	btChunk*	allocate(size_t size, int numElements) = 0;
80 
81 	virtual	void	finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0;
82 
83 	virtual	 void*	findPointer(void* oldPtr)  = 0;
84 
85 	virtual	void*	getUniquePointer(void*oldPtr) = 0;
86 
87 	virtual	void	startSerialization() = 0;
88 
89 	virtual	void	finishSerialization() = 0;
90 
91 	virtual	const char*	findNameForPointer(const void* ptr) const = 0;
92 
93 	virtual	void	registerNameForPointer(const void* ptr, const char* name) = 0;
94 
95 	virtual void	serializeName(const char* ptr) = 0;
96 
97 	virtual int		getSerializationFlags() const = 0;
98 
99 	virtual void	setSerializationFlags(int flags) = 0;
100 
101 	virtual int getNumChunks() const = 0;
102 
103 	virtual const btChunk* getChunk(int chunkIndex) const = 0;
104 
105 };
106 
107 
108 
109 #define BT_HEADER_LENGTH 12
110 #if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
111 #	define BT_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
112 #else
113 #	define BT_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
114 #endif
115 
116 
117 #define BT_MULTIBODY_CODE       BT_MAKE_ID('M','B','D','Y')
118 #define BT_SOFTBODY_CODE		BT_MAKE_ID('S','B','D','Y')
119 #define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C','O','B','J')
120 #define BT_RIGIDBODY_CODE		BT_MAKE_ID('R','B','D','Y')
121 #define BT_CONSTRAINT_CODE		BT_MAKE_ID('C','O','N','S')
122 #define BT_BOXSHAPE_CODE		BT_MAKE_ID('B','O','X','S')
123 #define BT_QUANTIZED_BVH_CODE	BT_MAKE_ID('Q','B','V','H')
124 #define BT_TRIANLGE_INFO_MAP	BT_MAKE_ID('T','M','A','P')
125 #define BT_SHAPE_CODE			BT_MAKE_ID('S','H','A','P')
126 #define BT_ARRAY_CODE			BT_MAKE_ID('A','R','A','Y')
127 #define BT_SBMATERIAL_CODE		BT_MAKE_ID('S','B','M','T')
128 #define BT_SBNODE_CODE			BT_MAKE_ID('S','B','N','D')
129 #define BT_DYNAMICSWORLD_CODE	BT_MAKE_ID('D','W','L','D')
130 #define BT_DNA_CODE				BT_MAKE_ID('D','N','A','1')
131 
132 
133 struct	btPointerUid
134 {
135 	union
136 	{
137 		void*	m_ptr;
138 		int		m_uniqueIds[2];
139 	};
140 };
141 
142 struct btBulletSerializedArrays
143 {
btBulletSerializedArraysbtBulletSerializedArrays144 	btBulletSerializedArrays()
145 	{
146 	}
147 	btAlignedObjectArray<struct btQuantizedBvhDoubleData*>	m_bvhsDouble;
148 	btAlignedObjectArray<struct btQuantizedBvhFloatData*>	m_bvhsFloat;
149 	btAlignedObjectArray<struct btCollisionShapeData*> m_colShapeData;
150 	btAlignedObjectArray<struct btDynamicsWorldDoubleData*> m_dynamicWorldInfoDataDouble;
151 	btAlignedObjectArray<struct btDynamicsWorldFloatData*> m_dynamicWorldInfoDataFloat;
152 	btAlignedObjectArray<struct btRigidBodyDoubleData*> m_rigidBodyDataDouble;
153 	btAlignedObjectArray<struct btRigidBodyFloatData*> m_rigidBodyDataFloat;
154 	btAlignedObjectArray<struct btCollisionObjectDoubleData*> m_collisionObjectDataDouble;
155 	btAlignedObjectArray<struct btCollisionObjectFloatData*> m_collisionObjectDataFloat;
156 	btAlignedObjectArray<struct btTypedConstraintFloatData*> m_constraintDataFloat;
157 	btAlignedObjectArray<struct btTypedConstraintDoubleData*> m_constraintDataDouble;
158 	btAlignedObjectArray<struct btTypedConstraintData*> m_constraintData;//for backwards compatibility
159 	btAlignedObjectArray<struct btSoftBodyFloatData*> m_softBodyFloatData;
160 	btAlignedObjectArray<struct btSoftBodyDoubleData*> m_softBodyDoubleData;
161 
162 };
163 
164 
165 ///The btDefaultSerializer is the main Bullet serialization class.
166 ///The constructor takes an optional argument for backwards compatibility, it is recommended to leave this empty/zero.
167 class btDefaultSerializer	:	public btSerializer
168 {
169 
170 protected:
171 
172 	btAlignedObjectArray<char*>			mTypes;
173 	btAlignedObjectArray<short*>			mStructs;
174 	btAlignedObjectArray<short>			mTlens;
175 	btHashMap<btHashInt, int>			mStructReverse;
176 	btHashMap<btHashString,int>	mTypeLookup;
177 
178 
179 
180 	btHashMap<btHashPtr,void*>	m_chunkP;
181 
182 	btHashMap<btHashPtr,const char*>	m_nameMap;
183 
184 	btHashMap<btHashPtr,btPointerUid>	m_uniquePointers;
185 	int	m_uniqueIdGenerator;
186 
187 	int					m_totalSize;
188 	unsigned char*		m_buffer;
189 	bool                m_ownsBuffer;
190 	int					m_currentSize;
191 	void*				m_dna;
192 	int					m_dnaLength;
193 
194 	int					m_serializationFlags;
195 
196 
197 	btAlignedObjectArray<btChunk*>	m_chunkPtrs;
198 
199 protected:
200 
201 
findPointer(void * oldPtr)202 	virtual	void*	findPointer(void* oldPtr)
203 	{
204 		void** ptr = m_chunkP.find(oldPtr);
205 		if (ptr && *ptr)
206 			return *ptr;
207 		return 0;
208 	}
209 
210 
211 
212 
213 
writeDNA()214 		virtual void	writeDNA()
215 		{
216 			btChunk* dnaChunk = allocate(m_dnaLength,1);
217 			memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength);
218 			finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna);
219 		}
220 
getReverseType(const char * type)221 		int getReverseType(const char *type) const
222 		{
223 
224 			btHashString key(type);
225 			const int* valuePtr = mTypeLookup.find(key);
226 			if (valuePtr)
227 				return *valuePtr;
228 
229 			return -1;
230 		}
231 
initDNA(const char * bdnaOrg,int dnalen)232 		void initDNA(const char* bdnaOrg,int dnalen)
233 		{
234 			///was already initialized
235 			if (m_dna)
236 				return;
237 
238 			int littleEndian= 1;
239 			littleEndian= ((char*)&littleEndian)[0];
240 
241 
242 			m_dna = btAlignedAlloc(dnalen,16);
243 			memcpy(m_dna,bdnaOrg,dnalen);
244 			m_dnaLength = dnalen;
245 
246 			int *intPtr=0;
247 			short *shtPtr=0;
248 			char *cp = 0;int dataLen =0;
249 			intPtr = (int*)m_dna;
250 
251 			/*
252 				SDNA (4 bytes) (magic number)
253 				NAME (4 bytes)
254 				<nr> (4 bytes) amount of names (int)
255 				<string>
256 				<string>
257 			*/
258 
259 			if (strncmp((const char*)m_dna, "SDNA", 4)==0)
260 			{
261 				// skip ++ NAME
262 				intPtr++; intPtr++;
263 			}
264 
265 			// Parse names
266 			if (!littleEndian)
267 				*intPtr = btSwapEndian(*intPtr);
268 
269 			dataLen = *intPtr;
270 
271 			intPtr++;
272 
273 			cp = (char*)intPtr;
274 			int i;
275 			for ( i=0; i<dataLen; i++)
276 			{
277 
278 				while (*cp)cp++;
279 				cp++;
280 			}
281 			cp = btAlignPointer(cp,4);
282 
283 			/*
284 				TYPE (4 bytes)
285 				<nr> amount of types (int)
286 				<string>
287 				<string>
288 			*/
289 
290 			intPtr = (int*)cp;
291 			btAssert(strncmp(cp, "TYPE", 4)==0); intPtr++;
292 
293 			if (!littleEndian)
294 				*intPtr =  btSwapEndian(*intPtr);
295 
296 			dataLen = *intPtr;
297 			intPtr++;
298 
299 
300 			cp = (char*)intPtr;
301 			for (i=0; i<dataLen; i++)
302 			{
303 				mTypes.push_back(cp);
304 				while (*cp)cp++;
305 				cp++;
306 			}
307 
308 			cp = btAlignPointer(cp,4);
309 
310 
311 			/*
312 				TLEN (4 bytes)
313 				<len> (short) the lengths of types
314 				<len>
315 			*/
316 
317 			// Parse type lens
318 			intPtr = (int*)cp;
319 			btAssert(strncmp(cp, "TLEN", 4)==0); intPtr++;
320 
321 			dataLen = (int)mTypes.size();
322 
323 			shtPtr = (short*)intPtr;
324 			for (i=0; i<dataLen; i++, shtPtr++)
325 			{
326 				if (!littleEndian)
327 					shtPtr[0] = btSwapEndian(shtPtr[0]);
328 				mTlens.push_back(shtPtr[0]);
329 			}
330 
331 			if (dataLen & 1) shtPtr++;
332 
333 			/*
334 				STRC (4 bytes)
335 				<nr> amount of structs (int)
336 				<typenr>
337 				<nr_of_elems>
338 				<typenr>
339 				<namenr>
340 				<typenr>
341 				<namenr>
342 			*/
343 
344 			intPtr = (int*)shtPtr;
345 			cp = (char*)intPtr;
346 			btAssert(strncmp(cp, "STRC", 4)==0); intPtr++;
347 
348 			if (!littleEndian)
349 				*intPtr = btSwapEndian(*intPtr);
350 			dataLen = *intPtr ;
351 			intPtr++;
352 
353 
354 			shtPtr = (short*)intPtr;
355 			for (i=0; i<dataLen; i++)
356 			{
357 				mStructs.push_back (shtPtr);
358 
359 				if (!littleEndian)
360 				{
361 					shtPtr[0]= btSwapEndian(shtPtr[0]);
362 					shtPtr[1]= btSwapEndian(shtPtr[1]);
363 
364 					int len = shtPtr[1];
365 					shtPtr+= 2;
366 
367 					for (int a=0; a<len; a++, shtPtr+=2)
368 					{
369 							shtPtr[0]= btSwapEndian(shtPtr[0]);
370 							shtPtr[1]= btSwapEndian(shtPtr[1]);
371 					}
372 
373 				} else
374 				{
375 					shtPtr+= (2*shtPtr[1])+2;
376 				}
377 			}
378 
379 			// build reverse lookups
380 			for (i=0; i<(int)mStructs.size(); i++)
381 			{
382 				short *strc = mStructs.at(i);
383 				mStructReverse.insert(strc[0], i);
384 				mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
385 			}
386 		}
387 
388 public:
389 
390 	btHashMap<btHashPtr,void*> m_skipPointers;
391 
392 
393 		btDefaultSerializer(int totalSize=0, unsigned char*	buffer=0)
m_totalSize(totalSize)394 			:m_totalSize(totalSize),
395 			m_currentSize(0),
396 			m_dna(0),
397 			m_dnaLength(0),
398 			m_serializationFlags(0)
399 		{
400 		    if (buffer==0)
401             {
402                 m_buffer = m_totalSize?(unsigned char*)btAlignedAlloc(totalSize,16):0;
403                 m_ownsBuffer = true;
404             } else
405             {
406                 m_buffer = buffer;
407                 m_ownsBuffer = false;
408             }
409 
410 			const bool VOID_IS_8 = ((sizeof(void*)==8));
411 
412 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
413 			if (VOID_IS_8)
414 			{
415 #if _WIN64
416 				initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
417 #else
418 				btAssert(0);
419 #endif
420 			} else
421 			{
422 #ifndef _WIN64
423 				initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
424 #else
425 				btAssert(0);
426 #endif
427 			}
428 
429 #else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
430 			if (VOID_IS_8)
431 			{
432 				initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
433 			} else
434 			{
435 				initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
436 			}
437 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
438 
439 		}
440 
~btDefaultSerializer()441 		virtual ~btDefaultSerializer()
442 		{
443 			if (m_buffer && m_ownsBuffer)
444 				btAlignedFree(m_buffer);
445 			if (m_dna)
446 				btAlignedFree(m_dna);
447 		}
448 
insertHeader()449 		void	insertHeader()
450 		{
451 			writeHeader(m_buffer);
452 			m_currentSize += BT_HEADER_LENGTH;
453 		}
454 
writeHeader(unsigned char * buffer)455 		void	writeHeader(unsigned char* buffer) const
456 		{
457 
458 
459 #ifdef  BT_USE_DOUBLE_PRECISION
460 			memcpy(buffer, "BULLETd", 7);
461 #else
462 			memcpy(buffer, "BULLETf", 7);
463 #endif //BT_USE_DOUBLE_PRECISION
464 
465 			int littleEndian= 1;
466 			littleEndian= ((char*)&littleEndian)[0];
467 
468 			if (sizeof(void*)==8)
469 			{
470 				buffer[7] = '-';
471 			} else
472 			{
473 				buffer[7] = '_';
474 			}
475 
476 			if (littleEndian)
477 			{
478 				buffer[8]='v';
479 			} else
480 			{
481 				buffer[8]='V';
482 			}
483 
484 
485 			buffer[9] = '2';
486 			buffer[10] = '8';
487 			buffer[11] = '4';
488 
489 		}
490 
startSerialization()491 		virtual	void	startSerialization()
492 		{
493 			m_uniqueIdGenerator= 1;
494 			if (m_totalSize)
495 			{
496 				unsigned char* buffer = internalAlloc(BT_HEADER_LENGTH);
497 				writeHeader(buffer);
498 			}
499 
500 		}
501 
finishSerialization()502 		virtual	void	finishSerialization()
503 		{
504 			writeDNA();
505 
506 			//if we didn't pre-allocate a buffer, we need to create a contiguous buffer now
507 			int mysize = 0;
508 			if (!m_totalSize)
509 			{
510 				if (m_buffer)
511 					btAlignedFree(m_buffer);
512 
513 				m_currentSize += BT_HEADER_LENGTH;
514 				m_buffer = (unsigned char*)btAlignedAlloc(m_currentSize,16);
515 
516 				unsigned char* currentPtr = m_buffer;
517 				writeHeader(m_buffer);
518 				currentPtr += BT_HEADER_LENGTH;
519 				mysize+=BT_HEADER_LENGTH;
520 				for (int i=0;i<	m_chunkPtrs.size();i++)
521 				{
522 					int curLength = sizeof(btChunk)+m_chunkPtrs[i]->m_length;
523 					memcpy(currentPtr,m_chunkPtrs[i], curLength);
524 					btAlignedFree(m_chunkPtrs[i]);
525 					currentPtr+=curLength;
526 					mysize+=curLength;
527 				}
528 			}
529 
530 			mTypes.clear();
531 			mStructs.clear();
532 			mTlens.clear();
533 			mStructReverse.clear();
534 			mTypeLookup.clear();
535 			m_skipPointers.clear();
536 			m_chunkP.clear();
537 			m_nameMap.clear();
538 			m_uniquePointers.clear();
539 			m_chunkPtrs.clear();
540 		}
541 
getUniquePointer(void * oldPtr)542 		virtual	void*	getUniquePointer(void*oldPtr)
543 		{
544 			if (!oldPtr)
545 				return 0;
546 
547 			btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
548 			if (uptr)
549 			{
550 				return uptr->m_ptr;
551 			}
552 
553 			void** ptr2 = m_skipPointers[oldPtr];
554             if (ptr2)
555 			{
556 				return 0;
557 			}
558 
559 			m_uniqueIdGenerator++;
560 
561 			btPointerUid uid;
562 			uid.m_uniqueIds[0] = m_uniqueIdGenerator;
563 			uid.m_uniqueIds[1] = m_uniqueIdGenerator;
564 			m_uniquePointers.insert(oldPtr,uid);
565 			return uid.m_ptr;
566 
567 		}
568 
getBufferPointer()569 		virtual	const unsigned char*		getBufferPointer() const
570 		{
571 			return m_buffer;
572 		}
573 
getCurrentBufferSize()574 		virtual	int					getCurrentBufferSize() const
575 		{
576 			return	m_currentSize;
577 		}
578 
finalizeChunk(btChunk * chunk,const char * structType,int chunkCode,void * oldPtr)579 		virtual	void	finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
580 		{
581 			if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
582 			{
583 				btAssert(!findPointer(oldPtr));
584 			}
585 
586 			chunk->m_dna_nr = getReverseType(structType);
587 
588 			chunk->m_chunkCode = chunkCode;
589 
590 			void* uniquePtr = getUniquePointer(oldPtr);
591 
592 			m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr);
593 			chunk->m_oldPtr = uniquePtr;//oldPtr;
594 
595 		}
596 
597 
internalAlloc(size_t size)598 		virtual unsigned char* internalAlloc(size_t size)
599 		{
600 			unsigned char* ptr = 0;
601 
602 			if (m_totalSize)
603 			{
604 				ptr = m_buffer+m_currentSize;
605 				m_currentSize += int(size);
606 				btAssert(m_currentSize<m_totalSize);
607 			} else
608 			{
609 				ptr = (unsigned char*)btAlignedAlloc(size,16);
610 				m_currentSize += int(size);
611 			}
612 			return ptr;
613 		}
614 
615 
616 
allocate(size_t size,int numElements)617 		virtual	btChunk*	allocate(size_t size, int numElements)
618 		{
619 
620 			unsigned char* ptr = internalAlloc(int(size)*numElements+sizeof(btChunk));
621 
622 			unsigned char* data = ptr + sizeof(btChunk);
623 
624 			btChunk* chunk = (btChunk*)ptr;
625 			chunk->m_chunkCode = 0;
626 			chunk->m_oldPtr = data;
627 			chunk->m_length = int(size)*numElements;
628 			chunk->m_number = numElements;
629 
630 			m_chunkPtrs.push_back(chunk);
631 
632 
633 			return chunk;
634 		}
635 
findNameForPointer(const void * ptr)636 		virtual	const char*	findNameForPointer(const void* ptr) const
637 		{
638 			const char*const * namePtr = m_nameMap.find(ptr);
639 			if (namePtr && *namePtr)
640 				return *namePtr;
641 			return 0;
642 
643 		}
644 
registerNameForPointer(const void * ptr,const char * name)645 		virtual	void	registerNameForPointer(const void* ptr, const char* name)
646 		{
647 			m_nameMap.insert(ptr,name);
648 		}
649 
serializeName(const char * name)650 		virtual void	serializeName(const char* name)
651 		{
652 			if (name)
653 			{
654 				//don't serialize name twice
655 				if (findPointer((void*)name))
656 					return;
657 
658 				int len = btStrLen(name);
659 				if (len)
660 				{
661 
662 					int newLen = len+1;
663 					int padding = ((newLen+3)&~3)-newLen;
664 					newLen += padding;
665 
666 					//serialize name string now
667 					btChunk* chunk = allocate(sizeof(char),newLen);
668 					char* destinationName = (char*)chunk->m_oldPtr;
669 					for (int i=0;i<len;i++)
670 					{
671 						destinationName[i] = name[i];
672 					}
673 					destinationName[len] = 0;
674 					finalizeChunk(chunk,"char",BT_ARRAY_CODE,(void*)name);
675 				}
676 			}
677 		}
678 
getSerializationFlags()679 		virtual int		getSerializationFlags() const
680 		{
681 			return m_serializationFlags;
682 		}
683 
setSerializationFlags(int flags)684 		virtual void	setSerializationFlags(int flags)
685 		{
686 			m_serializationFlags = flags;
687 		}
getNumChunks()688 		int getNumChunks() const
689 		{
690 			return m_chunkPtrs.size();
691 		}
692 
getChunk(int chunkIndex)693 		const btChunk* getChunk(int chunkIndex) const
694 		{
695 			return m_chunkPtrs[chunkIndex];
696 		}
697 };
698 
699 
700 ///In general it is best to use btDefaultSerializer,
701 ///in particular when writing the data to disk or sending it over the network.
702 ///The btInMemorySerializer is experimental and only suitable in a few cases.
703 ///The btInMemorySerializer takes a shortcut and can be useful to create a deep-copy
704 ///of objects. There will be a demo on how to use the btInMemorySerializer.
705 #ifdef ENABLE_INMEMORY_SERIALIZER
706 
707 struct btInMemorySerializer : public btDefaultSerializer
708 {
709     btHashMap<btHashPtr,btChunk*> m_uid2ChunkPtr;
710     btHashMap<btHashPtr,void*> m_orgPtr2UniqueDataPtr;
711     btHashMap<btHashString,const void*> m_names2Ptr;
712 
713 
714     btBulletSerializedArrays    m_arrays;
715 
716     btInMemorySerializer(int totalSize=0, unsigned char*	buffer=0)
btDefaultSerializerbtInMemorySerializer717     :btDefaultSerializer(totalSize,buffer)
718     {
719 
720     }
721 
startSerializationbtInMemorySerializer722     virtual void startSerialization()
723     {
724         m_uid2ChunkPtr.clear();
725         //todo: m_arrays.clear();
726         btDefaultSerializer::startSerialization();
727     }
728 
729 
730 
findChunkFromUniquePointerbtInMemorySerializer731     btChunk* findChunkFromUniquePointer(void* uniquePointer)
732     {
733         btChunk** chkPtr = m_uid2ChunkPtr[uniquePointer];
734         if (chkPtr)
735         {
736             return *chkPtr;
737         }
738         return 0;
739     }
740 
registerNameForPointerbtInMemorySerializer741 	virtual	void	registerNameForPointer(const void* ptr, const char* name)
742     {
743        btDefaultSerializer::registerNameForPointer(ptr,name);
744        m_names2Ptr.insert(name,ptr);
745     }
746 
finishSerializationbtInMemorySerializer747     virtual void finishSerialization()
748     {
749     }
750 
getUniquePointerbtInMemorySerializer751     virtual void* getUniquePointer(void*oldPtr)
752     {
753         if (oldPtr==0)
754             return 0;
755 
756         // void* uniquePtr = getUniquePointer(oldPtr);
757         btChunk* chunk = findChunkFromUniquePointer(oldPtr);
758         if (chunk)
759         {
760             return chunk->m_oldPtr;
761         } else
762         {
763             const char* n = (const char*) oldPtr;
764             const void** ptr = m_names2Ptr[n];
765             if (ptr)
766             {
767                 return oldPtr;
768             } else
769             {
770             		void** ptr2 = m_skipPointers[oldPtr];
771             		if (ptr2)
772 								{
773 									return 0;
774 								} else
775 								{
776 									//If this assert hit, serialization happened in the wrong order
777 									// 'getUniquePointer'
778 									btAssert(0);
779 								}
780 
781             }
782             return 0;
783         }
784 				return oldPtr;
785     }
786 
finalizeChunkbtInMemorySerializer787     virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
788     {
789         if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
790         {
791             btAssert(!findPointer(oldPtr));
792         }
793 
794         chunk->m_dna_nr = getReverseType(structType);
795         chunk->m_chunkCode = chunkCode;
796         //void* uniquePtr = getUniquePointer(oldPtr);
797         m_chunkP.insert(oldPtr,oldPtr);//chunk->m_oldPtr);
798         // chunk->m_oldPtr = uniquePtr;//oldPtr;
799 
800         void* uid = findPointer(oldPtr);
801         m_uid2ChunkPtr.insert(uid,chunk);
802 
803         switch (chunk->m_chunkCode)
804 			{
805 			case BT_SOFTBODY_CODE:
806 			{
807 	#ifdef BT_USE_DOUBLE_PRECISION
808 					m_arrays.m_softBodyDoubleData.push_back((btSoftBodyDoubleData*) chunk->m_oldPtr);
809 	#else
810 					m_arrays.m_softBodyFloatData.push_back((btSoftBodyFloatData*) chunk->m_oldPtr);
811 	#endif
812 					break;
813 				}
814 			case BT_COLLISIONOBJECT_CODE:
815 				{
816 	#ifdef BT_USE_DOUBLE_PRECISION
817 					m_arrays.m_collisionObjectDataDouble.push_back((btCollisionObjectDoubleData*)chunk->m_oldPtr);
818 	#else//BT_USE_DOUBLE_PRECISION
819 					m_arrays.m_collisionObjectDataFloat.push_back((btCollisionObjectFloatData*)chunk->m_oldPtr);
820 	#endif //BT_USE_DOUBLE_PRECISION
821 					break;
822 				}
823 			case BT_RIGIDBODY_CODE:
824 				{
825 	#ifdef BT_USE_DOUBLE_PRECISION
826 					m_arrays.m_rigidBodyDataDouble.push_back((btRigidBodyDoubleData*)chunk->m_oldPtr);
827 	#else
828 					m_arrays.m_rigidBodyDataFloat.push_back((btRigidBodyFloatData*)chunk->m_oldPtr);
829 	#endif//BT_USE_DOUBLE_PRECISION
830 					break;
831 				};
832 			case BT_CONSTRAINT_CODE:
833 				{
834 	#ifdef BT_USE_DOUBLE_PRECISION
835 					m_arrays.m_constraintDataDouble.push_back((btTypedConstraintDoubleData*)chunk->m_oldPtr);
836 	#else
837 					m_arrays.m_constraintDataFloat.push_back((btTypedConstraintFloatData*)chunk->m_oldPtr);
838 	#endif
839 					break;
840 				}
841 			case BT_QUANTIZED_BVH_CODE:
842 				{
843 	#ifdef BT_USE_DOUBLE_PRECISION
844 					m_arrays.m_bvhsDouble.push_back((btQuantizedBvhDoubleData*) chunk->m_oldPtr);
845 	#else
846 					m_arrays.m_bvhsFloat.push_back((btQuantizedBvhFloatData*) chunk->m_oldPtr);
847 	#endif
848 					break;
849 				}
850 
851 			case BT_SHAPE_CODE:
852 				{
853 					btCollisionShapeData* shapeData = (btCollisionShapeData*) chunk->m_oldPtr;
854 					m_arrays.m_colShapeData.push_back(shapeData);
855 					break;
856 				}
857 			case BT_TRIANLGE_INFO_MAP:
858 			case BT_ARRAY_CODE:
859 			case BT_SBMATERIAL_CODE:
860 			case BT_SBNODE_CODE:
861 			case BT_DYNAMICSWORLD_CODE:
862 			case BT_DNA_CODE:
863 				{
864 					break;
865 				}
866 			default:
867 				{
868 				}
869 			};
870     }
871 
getNumChunksbtInMemorySerializer872     int getNumChunks() const
873     {
874         return m_uid2ChunkPtr.size();
875     }
876 
getChunkbtInMemorySerializer877     const btChunk* getChunk(int chunkIndex) const
878     {
879         return *m_uid2ChunkPtr.getAtIndex(chunkIndex);
880     }
881 
882 };
883 #endif //ENABLE_INMEMORY_SERIALIZER
884 
885 #endif //BT_SERIALIZER_H
886 
887