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 #define BT_SOFTBODY_CODE BT_MAKE_ID('S','B','D','Y')
117 #define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C','O','B','J')
118 #define BT_RIGIDBODY_CODE BT_MAKE_ID('R','B','D','Y')
119 #define BT_CONSTRAINT_CODE BT_MAKE_ID('C','O','N','S')
120 #define BT_BOXSHAPE_CODE BT_MAKE_ID('B','O','X','S')
121 #define BT_QUANTIZED_BVH_CODE BT_MAKE_ID('Q','B','V','H')
122 #define BT_TRIANLGE_INFO_MAP BT_MAKE_ID('T','M','A','P')
123 #define BT_SHAPE_CODE BT_MAKE_ID('S','H','A','P')
124 #define BT_ARRAY_CODE BT_MAKE_ID('A','R','A','Y')
125 #define BT_SBMATERIAL_CODE BT_MAKE_ID('S','B','M','T')
126 #define BT_SBNODE_CODE BT_MAKE_ID('S','B','N','D')
127 #define BT_DYNAMICSWORLD_CODE BT_MAKE_ID('D','W','L','D')
128 #define BT_DNA_CODE BT_MAKE_ID('D','N','A','1')
129
130
131 struct btPointerUid
132 {
133 union
134 {
135 void* m_ptr;
136 int m_uniqueIds[2];
137 };
138 };
139
140 struct btBulletSerializedArrays
141 {
btBulletSerializedArraysbtBulletSerializedArrays142 btBulletSerializedArrays()
143 {
144 }
145 btAlignedObjectArray<struct btQuantizedBvhDoubleData*> m_bvhsDouble;
146 btAlignedObjectArray<struct btQuantizedBvhFloatData*> m_bvhsFloat;
147 btAlignedObjectArray<struct btCollisionShapeData*> m_colShapeData;
148 btAlignedObjectArray<struct btDynamicsWorldDoubleData*> m_dynamicWorldInfoDataDouble;
149 btAlignedObjectArray<struct btDynamicsWorldFloatData*> m_dynamicWorldInfoDataFloat;
150 btAlignedObjectArray<struct btRigidBodyDoubleData*> m_rigidBodyDataDouble;
151 btAlignedObjectArray<struct btRigidBodyFloatData*> m_rigidBodyDataFloat;
152 btAlignedObjectArray<struct btCollisionObjectDoubleData*> m_collisionObjectDataDouble;
153 btAlignedObjectArray<struct btCollisionObjectFloatData*> m_collisionObjectDataFloat;
154 btAlignedObjectArray<struct btTypedConstraintFloatData*> m_constraintDataFloat;
155 btAlignedObjectArray<struct btTypedConstraintDoubleData*> m_constraintDataDouble;
156 btAlignedObjectArray<struct btTypedConstraintData*> m_constraintData;//for backwards compatibility
157 btAlignedObjectArray<struct btSoftBodyFloatData*> m_softBodyFloatData;
158 btAlignedObjectArray<struct btSoftBodyDoubleData*> m_softBodyDoubleData;
159
160 };
161
162
163 ///The btDefaultSerializer is the main Bullet serialization class.
164 ///The constructor takes an optional argument for backwards compatibility, it is recommended to leave this empty/zero.
165 class btDefaultSerializer : public btSerializer
166 {
167
168 protected:
169
170 btAlignedObjectArray<char*> mTypes;
171 btAlignedObjectArray<short*> mStructs;
172 btAlignedObjectArray<short> mTlens;
173 btHashMap<btHashInt, int> mStructReverse;
174 btHashMap<btHashString,int> mTypeLookup;
175
176
177 btHashMap<btHashPtr,void*> m_chunkP;
178
179 btHashMap<btHashPtr,const char*> m_nameMap;
180
181 btHashMap<btHashPtr,btPointerUid> m_uniquePointers;
182 int m_uniqueIdGenerator;
183
184 int m_totalSize;
185 unsigned char* m_buffer;
186 int m_currentSize;
187 void* m_dna;
188 int m_dnaLength;
189
190 int m_serializationFlags;
191
192
193 btAlignedObjectArray<btChunk*> m_chunkPtrs;
194
195 protected:
196
findPointer(void * oldPtr)197 virtual void* findPointer(void* oldPtr)
198 {
199 void** ptr = m_chunkP.find(oldPtr);
200 if (ptr && *ptr)
201 return *ptr;
202 return 0;
203 }
204
205
206
207
208
writeDNA()209 void writeDNA()
210 {
211 btChunk* dnaChunk = allocate(m_dnaLength,1);
212 memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength);
213 finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna);
214 }
215
getReverseType(const char * type)216 int getReverseType(const char *type) const
217 {
218
219 btHashString key(type);
220 const int* valuePtr = mTypeLookup.find(key);
221 if (valuePtr)
222 return *valuePtr;
223
224 return -1;
225 }
226
initDNA(const char * bdnaOrg,int dnalen)227 void initDNA(const char* bdnaOrg,int dnalen)
228 {
229 ///was already initialized
230 if (m_dna)
231 return;
232
233 int littleEndian= 1;
234 littleEndian= ((char*)&littleEndian)[0];
235
236
237 m_dna = btAlignedAlloc(dnalen,16);
238 memcpy(m_dna,bdnaOrg,dnalen);
239 m_dnaLength = dnalen;
240
241 int *intPtr=0;
242 short *shtPtr=0;
243 char *cp = 0;int dataLen =0;
244 intPtr = (int*)m_dna;
245
246 /*
247 SDNA (4 bytes) (magic number)
248 NAME (4 bytes)
249 <nr> (4 bytes) amount of names (int)
250 <string>
251 <string>
252 */
253
254 if (strncmp((const char*)m_dna, "SDNA", 4)==0)
255 {
256 // skip ++ NAME
257 intPtr++; intPtr++;
258 }
259
260 // Parse names
261 if (!littleEndian)
262 *intPtr = btSwapEndian(*intPtr);
263
264 dataLen = *intPtr;
265
266 intPtr++;
267
268 cp = (char*)intPtr;
269 int i;
270 for ( i=0; i<dataLen; i++)
271 {
272
273 while (*cp)cp++;
274 cp++;
275 }
276 cp = btAlignPointer(cp,4);
277
278 /*
279 TYPE (4 bytes)
280 <nr> amount of types (int)
281 <string>
282 <string>
283 */
284
285 intPtr = (int*)cp;
286 btAssert(strncmp(cp, "TYPE", 4)==0); intPtr++;
287
288 if (!littleEndian)
289 *intPtr = btSwapEndian(*intPtr);
290
291 dataLen = *intPtr;
292 intPtr++;
293
294
295 cp = (char*)intPtr;
296 for (i=0; i<dataLen; i++)
297 {
298 mTypes.push_back(cp);
299 while (*cp)cp++;
300 cp++;
301 }
302
303 cp = btAlignPointer(cp,4);
304
305
306 /*
307 TLEN (4 bytes)
308 <len> (short) the lengths of types
309 <len>
310 */
311
312 // Parse type lens
313 intPtr = (int*)cp;
314 btAssert(strncmp(cp, "TLEN", 4)==0); intPtr++;
315
316 dataLen = (int)mTypes.size();
317
318 shtPtr = (short*)intPtr;
319 for (i=0; i<dataLen; i++, shtPtr++)
320 {
321 if (!littleEndian)
322 shtPtr[0] = btSwapEndian(shtPtr[0]);
323 mTlens.push_back(shtPtr[0]);
324 }
325
326 if (dataLen & 1) shtPtr++;
327
328 /*
329 STRC (4 bytes)
330 <nr> amount of structs (int)
331 <typenr>
332 <nr_of_elems>
333 <typenr>
334 <namenr>
335 <typenr>
336 <namenr>
337 */
338
339 intPtr = (int*)shtPtr;
340 cp = (char*)intPtr;
341 btAssert(strncmp(cp, "STRC", 4)==0); intPtr++;
342
343 if (!littleEndian)
344 *intPtr = btSwapEndian(*intPtr);
345 dataLen = *intPtr ;
346 intPtr++;
347
348
349 shtPtr = (short*)intPtr;
350 for (i=0; i<dataLen; i++)
351 {
352 mStructs.push_back (shtPtr);
353
354 if (!littleEndian)
355 {
356 shtPtr[0]= btSwapEndian(shtPtr[0]);
357 shtPtr[1]= btSwapEndian(shtPtr[1]);
358
359 int len = shtPtr[1];
360 shtPtr+= 2;
361
362 for (int a=0; a<len; a++, shtPtr+=2)
363 {
364 shtPtr[0]= btSwapEndian(shtPtr[0]);
365 shtPtr[1]= btSwapEndian(shtPtr[1]);
366 }
367
368 } else
369 {
370 shtPtr+= (2*shtPtr[1])+2;
371 }
372 }
373
374 // build reverse lookups
375 for (i=0; i<(int)mStructs.size(); i++)
376 {
377 short *strc = mStructs.at(i);
378 mStructReverse.insert(strc[0], i);
379 mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
380 }
381 }
382
383 public:
384
385
386
387
388 btDefaultSerializer(int totalSize=0)
m_totalSize(totalSize)389 :m_totalSize(totalSize),
390 m_currentSize(0),
391 m_dna(0),
392 m_dnaLength(0),
393 m_serializationFlags(0)
394 {
395 m_buffer = m_totalSize?(unsigned char*)btAlignedAlloc(totalSize,16):0;
396
397 const bool VOID_IS_8 = ((sizeof(void*)==8));
398
399 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
400 if (VOID_IS_8)
401 {
402 #if _WIN64
403 initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
404 #else
405 btAssert(0);
406 #endif
407 } else
408 {
409 #ifndef _WIN64
410 initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
411 #else
412 btAssert(0);
413 #endif
414 }
415
416 #else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
417 if (VOID_IS_8)
418 {
419 initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
420 } else
421 {
422 initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
423 }
424 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
425
426 }
427
~btDefaultSerializer()428 virtual ~btDefaultSerializer()
429 {
430 if (m_buffer)
431 btAlignedFree(m_buffer);
432 if (m_dna)
433 btAlignedFree(m_dna);
434 }
435
writeHeader(unsigned char * buffer)436 void writeHeader(unsigned char* buffer) const
437 {
438
439
440 #ifdef BT_USE_DOUBLE_PRECISION
441 memcpy(buffer, "BULLETd", 7);
442 #else
443 memcpy(buffer, "BULLETf", 7);
444 #endif //BT_USE_DOUBLE_PRECISION
445
446 int littleEndian= 1;
447 littleEndian= ((char*)&littleEndian)[0];
448
449 if (sizeof(void*)==8)
450 {
451 buffer[7] = '-';
452 } else
453 {
454 buffer[7] = '_';
455 }
456
457 if (littleEndian)
458 {
459 buffer[8]='v';
460 } else
461 {
462 buffer[8]='V';
463 }
464
465
466 buffer[9] = '2';
467 buffer[10] = '8';
468 buffer[11] = '3';
469
470 }
471
startSerialization()472 virtual void startSerialization()
473 {
474 m_uniqueIdGenerator= 1;
475 if (m_totalSize)
476 {
477 unsigned char* buffer = internalAlloc(BT_HEADER_LENGTH);
478 writeHeader(buffer);
479 }
480
481 }
482
finishSerialization()483 virtual void finishSerialization()
484 {
485 writeDNA();
486
487 //if we didn't pre-allocate a buffer, we need to create a contiguous buffer now
488 int mysize = 0;
489 if (!m_totalSize)
490 {
491 if (m_buffer)
492 btAlignedFree(m_buffer);
493
494 m_currentSize += BT_HEADER_LENGTH;
495 m_buffer = (unsigned char*)btAlignedAlloc(m_currentSize,16);
496
497 unsigned char* currentPtr = m_buffer;
498 writeHeader(m_buffer);
499 currentPtr += BT_HEADER_LENGTH;
500 mysize+=BT_HEADER_LENGTH;
501 for (int i=0;i< m_chunkPtrs.size();i++)
502 {
503 int curLength = sizeof(btChunk)+m_chunkPtrs[i]->m_length;
504 memcpy(currentPtr,m_chunkPtrs[i], curLength);
505 btAlignedFree(m_chunkPtrs[i]);
506 currentPtr+=curLength;
507 mysize+=curLength;
508 }
509 }
510
511 mTypes.clear();
512 mStructs.clear();
513 mTlens.clear();
514 mStructReverse.clear();
515 mTypeLookup.clear();
516 m_chunkP.clear();
517 m_nameMap.clear();
518 m_uniquePointers.clear();
519 m_chunkPtrs.clear();
520 }
521
getUniquePointer(void * oldPtr)522 virtual void* getUniquePointer(void*oldPtr)
523 {
524 if (!oldPtr)
525 return 0;
526
527 btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
528 if (uptr)
529 {
530 return uptr->m_ptr;
531 }
532 m_uniqueIdGenerator++;
533
534 btPointerUid uid;
535 uid.m_uniqueIds[0] = m_uniqueIdGenerator;
536 uid.m_uniqueIds[1] = m_uniqueIdGenerator;
537 m_uniquePointers.insert(oldPtr,uid);
538 return uid.m_ptr;
539
540 }
541
getBufferPointer()542 virtual const unsigned char* getBufferPointer() const
543 {
544 return m_buffer;
545 }
546
getCurrentBufferSize()547 virtual int getCurrentBufferSize() const
548 {
549 return m_currentSize;
550 }
551
finalizeChunk(btChunk * chunk,const char * structType,int chunkCode,void * oldPtr)552 virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
553 {
554 if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
555 {
556 btAssert(!findPointer(oldPtr));
557 }
558
559 chunk->m_dna_nr = getReverseType(structType);
560
561 chunk->m_chunkCode = chunkCode;
562
563 void* uniquePtr = getUniquePointer(oldPtr);
564
565 m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr);
566 chunk->m_oldPtr = uniquePtr;//oldPtr;
567
568 }
569
570
internalAlloc(size_t size)571 virtual unsigned char* internalAlloc(size_t size)
572 {
573 unsigned char* ptr = 0;
574
575 if (m_totalSize)
576 {
577 ptr = m_buffer+m_currentSize;
578 m_currentSize += int(size);
579 btAssert(m_currentSize<m_totalSize);
580 } else
581 {
582 ptr = (unsigned char*)btAlignedAlloc(size,16);
583 m_currentSize += int(size);
584 }
585 return ptr;
586 }
587
588
589
allocate(size_t size,int numElements)590 virtual btChunk* allocate(size_t size, int numElements)
591 {
592
593 unsigned char* ptr = internalAlloc(int(size)*numElements+sizeof(btChunk));
594
595 unsigned char* data = ptr + sizeof(btChunk);
596
597 btChunk* chunk = (btChunk*)ptr;
598 chunk->m_chunkCode = 0;
599 chunk->m_oldPtr = data;
600 chunk->m_length = int(size)*numElements;
601 chunk->m_number = numElements;
602
603 m_chunkPtrs.push_back(chunk);
604
605
606 return chunk;
607 }
608
findNameForPointer(const void * ptr)609 virtual const char* findNameForPointer(const void* ptr) const
610 {
611 const char*const * namePtr = m_nameMap.find(ptr);
612 if (namePtr && *namePtr)
613 return *namePtr;
614 return 0;
615
616 }
617
registerNameForPointer(const void * ptr,const char * name)618 virtual void registerNameForPointer(const void* ptr, const char* name)
619 {
620 m_nameMap.insert(ptr,name);
621 }
622
serializeName(const char * name)623 virtual void serializeName(const char* name)
624 {
625 if (name)
626 {
627 //don't serialize name twice
628 if (findPointer((void*)name))
629 return;
630
631 int len = btStrLen(name);
632 if (len)
633 {
634
635 int newLen = len+1;
636 int padding = ((newLen+3)&~3)-newLen;
637 newLen += padding;
638
639 //serialize name string now
640 btChunk* chunk = allocate(sizeof(char),newLen);
641 char* destinationName = (char*)chunk->m_oldPtr;
642 for (int i=0;i<len;i++)
643 {
644 destinationName[i] = name[i];
645 }
646 destinationName[len] = 0;
647 finalizeChunk(chunk,"char",BT_ARRAY_CODE,(void*)name);
648 }
649 }
650 }
651
getSerializationFlags()652 virtual int getSerializationFlags() const
653 {
654 return m_serializationFlags;
655 }
656
setSerializationFlags(int flags)657 virtual void setSerializationFlags(int flags)
658 {
659 m_serializationFlags = flags;
660 }
getNumChunks()661 int getNumChunks() const
662 {
663 return m_chunkPtrs.size();
664 }
665
getChunk(int chunkIndex)666 const btChunk* getChunk(int chunkIndex) const
667 {
668 return m_chunkPtrs[chunkIndex];
669 }
670 };
671
672
673 ///In general it is best to use btDefaultSerializer,
674 ///in particular when writing the data to disk or sending it over the network.
675 ///The btInMemorySerializer is experimental and only suitable in a few cases.
676 ///The btInMemorySerializer takes a shortcut and can be useful to create a deep-copy
677 ///of objects. There will be a demo on how to use the btInMemorySerializer.
678 #ifdef ENABLE_INMEMORY_SERIALIZER
679
680 struct btInMemorySerializer : public btDefaultSerializer
681 {
682 btHashMap<btHashPtr,btChunk*> m_uid2ChunkPtr;
683 btHashMap<btHashPtr,void*> m_orgPtr2UniqueDataPtr;
684 btHashMap<btHashString,const void*> m_names2Ptr;
685 btHashMap<btHashPtr,void*> m_skipPointers;
686
687 btBulletSerializedArrays m_arrays;
688
689
startSerializationbtInMemorySerializer690 virtual void startSerialization()
691 {
692 m_uid2ChunkPtr.clear();
693 //todo: m_arrays.clear();
694 btDefaultSerializer::startSerialization();
695 }
696
findChunkFromUniquePointerbtInMemorySerializer697 btChunk* findChunkFromUniquePointer(void* uniquePointer)
698 {
699 btChunk** chkPtr = m_uid2ChunkPtr[uniquePointer];
700 if (chkPtr)
701 {
702 return *chkPtr;
703 }
704 return 0;
705 }
706
registerNameForPointerbtInMemorySerializer707 virtual void registerNameForPointer(const void* ptr, const char* name)
708 {
709 btDefaultSerializer::registerNameForPointer(ptr,name);
710 m_names2Ptr.insert(name,ptr);
711 }
712
finishSerializationbtInMemorySerializer713 virtual void finishSerialization()
714 {
715 }
716
getUniquePointerbtInMemorySerializer717 virtual void* getUniquePointer(void*oldPtr)
718 {
719 if (oldPtr==0)
720 return 0;
721
722 // void* uniquePtr = getUniquePointer(oldPtr);
723 btChunk* chunk = findChunkFromUniquePointer(oldPtr);
724 if (chunk)
725 {
726 return chunk->m_oldPtr;
727 } else
728 {
729 const char* n = (const char*) oldPtr;
730 const void** ptr = m_names2Ptr[n];
731 if (ptr)
732 {
733 return oldPtr;
734 } else
735 {
736 void** ptr2 = m_skipPointers[oldPtr];
737 if (ptr2)
738 {
739 return 0;
740 } else
741 {
742 //If this assert hit, serialization happened in the wrong order
743 // 'getUniquePointer'
744 btAssert(0);
745 }
746
747 }
748 return 0;
749 }
750 return oldPtr;
751 }
752
finalizeChunkbtInMemorySerializer753 virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
754 {
755 if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
756 {
757 btAssert(!findPointer(oldPtr));
758 }
759
760 chunk->m_dna_nr = getReverseType(structType);
761 chunk->m_chunkCode = chunkCode;
762 //void* uniquePtr = getUniquePointer(oldPtr);
763 m_chunkP.insert(oldPtr,oldPtr);//chunk->m_oldPtr);
764 // chunk->m_oldPtr = uniquePtr;//oldPtr;
765
766 void* uid = findPointer(oldPtr);
767 m_uid2ChunkPtr.insert(uid,chunk);
768
769 switch (chunk->m_chunkCode)
770 {
771 case BT_SOFTBODY_CODE:
772 {
773 #ifdef BT_USE_DOUBLE_PRECISION
774 m_arrays.m_softBodyDoubleData.push_back((btSoftBodyDoubleData*) chunk->m_oldPtr);
775 #else
776 m_arrays.m_softBodyFloatData.push_back((btSoftBodyFloatData*) chunk->m_oldPtr);
777 #endif
778 break;
779 }
780 case BT_COLLISIONOBJECT_CODE:
781 {
782 #ifdef BT_USE_DOUBLE_PRECISION
783 m_arrays.m_collisionObjectDataDouble.push_back((btCollisionObjectDoubleData*)chunk->m_oldPtr);
784 #else//BT_USE_DOUBLE_PRECISION
785 m_arrays.m_collisionObjectDataFloat.push_back((btCollisionObjectFloatData*)chunk->m_oldPtr);
786 #endif //BT_USE_DOUBLE_PRECISION
787 break;
788 }
789 case BT_RIGIDBODY_CODE:
790 {
791 #ifdef BT_USE_DOUBLE_PRECISION
792 m_arrays.m_rigidBodyDataDouble.push_back((btRigidBodyDoubleData*)chunk->m_oldPtr);
793 #else
794 m_arrays.m_rigidBodyDataFloat.push_back((btRigidBodyFloatData*)chunk->m_oldPtr);
795 #endif//BT_USE_DOUBLE_PRECISION
796 break;
797 };
798 case BT_CONSTRAINT_CODE:
799 {
800 #ifdef BT_USE_DOUBLE_PRECISION
801 m_arrays.m_constraintDataDouble.push_back((btTypedConstraintDoubleData*)chunk->m_oldPtr);
802 #else
803 m_arrays.m_constraintDataFloat.push_back((btTypedConstraintFloatData*)chunk->m_oldPtr);
804 #endif
805 break;
806 }
807 case BT_QUANTIZED_BVH_CODE:
808 {
809 #ifdef BT_USE_DOUBLE_PRECISION
810 m_arrays.m_bvhsDouble.push_back((btQuantizedBvhDoubleData*) chunk->m_oldPtr);
811 #else
812 m_arrays.m_bvhsFloat.push_back((btQuantizedBvhFloatData*) chunk->m_oldPtr);
813 #endif
814 break;
815 }
816
817 case BT_SHAPE_CODE:
818 {
819 btCollisionShapeData* shapeData = (btCollisionShapeData*) chunk->m_oldPtr;
820 m_arrays.m_colShapeData.push_back(shapeData);
821 break;
822 }
823 case BT_TRIANLGE_INFO_MAP:
824 case BT_ARRAY_CODE:
825 case BT_SBMATERIAL_CODE:
826 case BT_SBNODE_CODE:
827 case BT_DYNAMICSWORLD_CODE:
828 case BT_DNA_CODE:
829 {
830 break;
831 }
832 default:
833 {
834 }
835 };
836 }
837
getNumChunksbtInMemorySerializer838 int getNumChunks() const
839 {
840 return m_uid2ChunkPtr.size();
841 }
842
getChunkbtInMemorySerializer843 const btChunk* getChunk(int chunkIndex) const
844 {
845 return *m_uid2ChunkPtr.getAtIndex(chunkIndex);
846 }
847
848 };
849 #endif //ENABLE_INMEMORY_SERIALIZER
850
851 #endif //BT_SERIALIZER_H
852
853