Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.h @ 8422

Last change on this file since 8422 was 8284, checked in by rgrieder, 14 years ago

Merged revisions 7978 - 8096 from kicklib to kicklib2.

  • Property svn:eol-style set to native
File size: 11.7 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. 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 "btStackAlloc.h"
21#include "btHashMap.h"
22
23#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
24#include <memory.h>
25#endif
26#include <string.h>
27
28
29
30///only the 32bit versions for now
31extern unsigned char sBulletDNAstr[];
32extern int sBulletDNAlen;
33extern unsigned char sBulletDNAstr64[];
34extern int sBulletDNAlen64;
35
36SIMD_FORCE_INLINE       int btStrLen(const char* str) 
37{
38    if (!str) 
39                return(0);
40        int len = 0;
41   
42        while (*str != 0)
43        {
44        str++;
45        len++;
46    }
47
48    return len;
49}
50
51
52class btChunk
53{
54public:
55        int             m_chunkCode;
56        int             m_length;
57        void    *m_oldPtr;
58        int             m_dna_nr;
59        int             m_number;
60};
61
62enum    btSerializationFlags
63{
64        BT_SERIALIZE_NO_BVH = 1,
65        BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2,
66        BT_SERIALIZE_NO_DUPLICATE_ASSERT = 4
67};
68
69class   btSerializer
70{
71
72public:
73
74        virtual ~btSerializer() {}
75
76        virtual const unsigned char*            getBufferPointer() const = 0;
77
78        virtual int             getCurrentBufferSize() const = 0;
79
80        virtual btChunk*        allocate(size_t size, int numElements) = 0;
81
82        virtual void    finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0;
83
84        virtual  void*  findPointer(void* oldPtr)  = 0;
85
86        virtual void*   getUniquePointer(void*oldPtr) = 0;
87
88        virtual void    startSerialization() = 0;
89       
90        virtual void    finishSerialization() = 0;
91
92        virtual const char*     findNameForPointer(const void* ptr) const = 0;
93
94        virtual void    registerNameForPointer(const void* ptr, const char* name) = 0;
95
96        virtual void    serializeName(const char* ptr) = 0;
97
98        virtual int             getSerializationFlags() const = 0;
99
100        virtual void    setSerializationFlags(int flags) = 0;
101
102
103};
104
105
106
107#define BT_HEADER_LENGTH 12
108#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
109#       define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
110#else
111#       define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
112#endif
113
114#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J')
115#define BT_RIGIDBODY_CODE               MAKE_ID('R','B','D','Y')
116#define BT_CONSTRAINT_CODE              MAKE_ID('C','O','N','S')
117#define BT_BOXSHAPE_CODE                MAKE_ID('B','O','X','S')
118#define BT_QUANTIZED_BVH_CODE   MAKE_ID('Q','B','V','H')
119#define BT_TRIANLGE_INFO_MAP    MAKE_ID('T','M','A','P')
120#define BT_SHAPE_CODE                   MAKE_ID('S','H','A','P')
121#define BT_ARRAY_CODE                   MAKE_ID('A','R','A','Y')
122#define BT_DNA_CODE                             MAKE_ID('D','N','A','1')
123
124
125
126struct  btPointerUid
127{
128        union
129        {
130                void*   m_ptr;
131                int             m_uniqueIds[2];
132        };
133};
134
135
136class btDefaultSerializer       :       public btSerializer
137{
138
139
140        btAlignedObjectArray<char*>                     mTypes;
141        btAlignedObjectArray<short*>                    mStructs;
142        btAlignedObjectArray<short>                     mTlens;
143        btHashMap<btHashInt, int>                       mStructReverse;
144        btHashMap<btHashString,int>     mTypeLookup;
145
146       
147        btHashMap<btHashPtr,void*>      m_chunkP;
148       
149        btHashMap<btHashPtr,const char*>        m_nameMap;
150
151        btHashMap<btHashPtr,btPointerUid>       m_uniquePointers;
152        int     m_uniqueIdGenerator;
153
154        int                                     m_totalSize;
155        unsigned char*          m_buffer;
156        int                                     m_currentSize;
157        void*                           m_dna;
158        int                                     m_dnaLength;
159
160        int                                     m_serializationFlags;
161
162
163        btAlignedObjectArray<btChunk*>  m_chunkPtrs;
164       
165protected:
166
167        virtual void*   findPointer(void* oldPtr) 
168        {
169                void** ptr = m_chunkP.find(oldPtr);
170                if (ptr && *ptr)
171                        return *ptr;
172                return 0;
173        }
174
175       
176
177
178
179                void    writeDNA()
180                {
181                        btChunk* dnaChunk = allocate(m_dnaLength,1);
182                        memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength);
183                        finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna);
184                }
185
186                int getReverseType(const char *type) const
187                {
188
189                        btHashString key(type);
190                        const int* valuePtr = mTypeLookup.find(key);
191                        if (valuePtr)
192                                return *valuePtr;
193                       
194                        return -1;
195                }
196
197                void initDNA(const char* bdnaOrg,int dnalen)
198                {
199                        ///was already initialized
200                        if (m_dna)
201                                return;
202
203                        int littleEndian= 1;
204                        littleEndian= ((char*)&littleEndian)[0];
205                       
206
207                        m_dna = btAlignedAlloc(dnalen,16);
208                        memcpy(m_dna,bdnaOrg,dnalen);
209                        m_dnaLength = dnalen;
210
211                        int *intPtr=0;
212                        short *shtPtr=0;
213                        char *cp = 0;int dataLen =0;long nr=0;
214                        intPtr = (int*)m_dna;
215
216                        /*
217                                SDNA (4 bytes) (magic number)
218                                NAME (4 bytes)
219                                <nr> (4 bytes) amount of names (int)
220                                <string>
221                                <string>
222                        */
223
224                        if (strncmp((const char*)m_dna, "SDNA", 4)==0)
225                        {
226                                // skip ++ NAME
227                                intPtr++; intPtr++;
228                        }
229
230                        // Parse names
231                        if (!littleEndian)
232                                *intPtr = btSwapEndian(*intPtr);
233                               
234                        dataLen = *intPtr;
235                       
236                        intPtr++;
237
238                        cp = (char*)intPtr;
239                        int i;
240                        for ( i=0; i<dataLen; i++)
241                        {
242                               
243                                while (*cp)cp++;
244                                cp++;
245                        }
246                        {
247                                nr= (long)cp;
248                        //      long mask=3;
249                                nr= ((nr+3)&~3)-nr;
250                                while (nr--)
251                                {
252                                        cp++;
253                                }
254                        }
255
256                        /*
257                                TYPE (4 bytes)
258                                <nr> amount of types (int)
259                                <string>
260                                <string>
261                        */
262
263                        intPtr = (int*)cp;
264                        assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
265
266                        if (!littleEndian)
267                                *intPtr =  btSwapEndian(*intPtr);
268                       
269                        dataLen = *intPtr;
270                        intPtr++;
271
272                       
273                        cp = (char*)intPtr;
274                        for (i=0; i<dataLen; i++)
275                        {
276                                mTypes.push_back(cp);
277                                while (*cp)cp++;
278                                cp++;
279                        }
280
281                {
282                                nr= (long)cp;
283                        //      long mask=3;
284                                nr= ((nr+3)&~3)-nr;
285                                while (nr--)
286                                {
287                                        cp++;
288                                }
289                        }
290
291
292                        /*
293                                TLEN (4 bytes)
294                                <len> (short) the lengths of types
295                                <len>
296                        */
297
298                        // Parse type lens
299                        intPtr = (int*)cp;
300                        assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
301
302                        dataLen = (int)mTypes.size();
303
304                        shtPtr = (short*)intPtr;
305                        for (i=0; i<dataLen; i++, shtPtr++)
306                        {
307                                if (!littleEndian)
308                                        shtPtr[0] = btSwapEndian(shtPtr[0]);
309                                mTlens.push_back(shtPtr[0]);
310                        }
311
312                        if (dataLen & 1) shtPtr++;
313
314                        /*
315                                STRC (4 bytes)
316                                <nr> amount of structs (int)
317                                <typenr>
318                                <nr_of_elems>
319                                <typenr>
320                                <namenr>
321                                <typenr>
322                                <namenr>
323                        */
324
325                        intPtr = (int*)shtPtr;
326                        cp = (char*)intPtr;
327                        assert(strncmp(cp, "STRC", 4)==0); intPtr++;
328
329                        if (!littleEndian)
330                                *intPtr = btSwapEndian(*intPtr);
331                        dataLen = *intPtr ; 
332                        intPtr++;
333
334
335                        shtPtr = (short*)intPtr;
336                        for (i=0; i<dataLen; i++)
337                        {
338                                mStructs.push_back (shtPtr);
339                               
340                                if (!littleEndian)
341                                {
342                                        shtPtr[0]= btSwapEndian(shtPtr[0]);
343                                        shtPtr[1]= btSwapEndian(shtPtr[1]);
344
345                                        int len = shtPtr[1];
346                                        shtPtr+= 2;
347
348                                        for (int a=0; a<len; a++, shtPtr+=2)
349                                        {
350                                                        shtPtr[0]= btSwapEndian(shtPtr[0]);
351                                                        shtPtr[1]= btSwapEndian(shtPtr[1]);
352                                        }
353
354                                } else
355                                {
356                                        shtPtr+= (2*shtPtr[1])+2;
357                                }
358                        }
359
360                        // build reverse lookups
361                        for (i=0; i<(int)mStructs.size(); i++)
362                        {
363                                short *strc = mStructs.at(i);
364                                mStructReverse.insert(strc[0], i);
365                                mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
366                        }
367                }
368
369public: 
370       
371
372       
373
374                btDefaultSerializer(int totalSize)
375                        :m_totalSize(totalSize),
376                        m_currentSize(0),
377                        m_dna(0),
378                        m_dnaLength(0),
379                        m_serializationFlags(0)
380                {
381                        m_buffer = (unsigned char*)btAlignedAlloc(totalSize, 16);
382                       
383                        const bool VOID_IS_8 = ((sizeof(void*)==8));
384
385#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
386                        if (VOID_IS_8)
387                        {
388#if _WIN64
389                                initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
390#else
391                                btAssert(0);
392#endif
393                        } else
394                        {
395#ifndef _WIN64
396                                initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
397#else
398                                btAssert(0);
399#endif
400                        }
401       
402#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
403                        if (VOID_IS_8)
404                        {
405                                initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
406                        } else
407                        {
408                                initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
409                        }
410#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
411       
412                }
413
414                virtual ~btDefaultSerializer() 
415                {
416                        if (m_buffer)
417                                btAlignedFree(m_buffer);
418                        if (m_dna)
419                                btAlignedFree(m_dna);
420                }
421
422                virtual void    startSerialization()
423                {
424                        m_uniqueIdGenerator= 1;
425
426                        m_currentSize = BT_HEADER_LENGTH;
427
428#ifdef  BT_USE_DOUBLE_PRECISION
429                        memcpy(m_buffer, "BULLETd", 7);
430#else
431                        memcpy(m_buffer, "BULLETf", 7);
432#endif //BT_USE_DOUBLE_PRECISION
433       
434                        int littleEndian= 1;
435                        littleEndian= ((char*)&littleEndian)[0];
436
437                        if (sizeof(void*)==8)
438                        {
439                                m_buffer[7] = '-';
440                        } else
441                        {
442                                m_buffer[7] = '_';
443                        }
444
445                        if (littleEndian)
446                        {
447                                m_buffer[8]='v';                               
448                        } else
449                        {
450                                m_buffer[8]='V';
451                        }
452
453
454                        m_buffer[9] = '2';
455                        m_buffer[10] = '7';
456                        m_buffer[11] = '7';
457
458                       
459                }
460
461                virtual void    finishSerialization()
462                {
463                        writeDNA();
464
465
466                        mTypes.clear();
467                        mStructs.clear();
468                        mTlens.clear();
469                        mStructReverse.clear();
470                        mTypeLookup.clear();
471                        m_chunkP.clear();
472                        m_nameMap.clear();
473                        m_uniquePointers.clear();
474                }
475
476                virtual void*   getUniquePointer(void*oldPtr)
477                {
478                        if (!oldPtr)
479                                return 0;
480
481                        btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
482                        if (uptr)
483                        {
484                                return uptr->m_ptr;
485                        }
486                        m_uniqueIdGenerator++;
487                       
488                        btPointerUid uid;
489                        uid.m_uniqueIds[0] = m_uniqueIdGenerator;
490                        uid.m_uniqueIds[1] = m_uniqueIdGenerator;
491                        m_uniquePointers.insert(oldPtr,uid);
492                        return uid.m_ptr;
493
494                }
495
496                virtual const unsigned char*            getBufferPointer() const
497                {
498                        return m_buffer;
499                }
500
501                virtual int                                     getCurrentBufferSize() const
502                {
503                        return  m_currentSize;
504                }
505
506                virtual void    finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
507                {
508                        if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
509                        {
510                                btAssert(!findPointer(oldPtr));
511                        }
512
513                        chunk->m_dna_nr = getReverseType(structType);
514                       
515                        chunk->m_chunkCode = chunkCode;
516                       
517                        void* uniquePtr = getUniquePointer(oldPtr);
518                       
519                        m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr);
520                        chunk->m_oldPtr = uniquePtr;//oldPtr;
521                       
522                }
523
524               
525
526               
527
528                virtual btChunk*        allocate(size_t size, int numElements)
529                {
530
531                        unsigned char* ptr = m_buffer+m_currentSize;
532                        m_currentSize += int(size)*numElements+sizeof(btChunk);
533                        btAssert(m_currentSize<m_totalSize);
534
535                        unsigned char* data = ptr + sizeof(btChunk);
536                       
537                        btChunk* chunk = (btChunk*)ptr;
538                        chunk->m_chunkCode = 0;
539                        chunk->m_oldPtr = data;
540                        chunk->m_length = int(size)*numElements;
541                        chunk->m_number = numElements;
542                       
543                        m_chunkPtrs.push_back(chunk);
544                       
545
546                        return chunk;
547                }
548
549                virtual const char*     findNameForPointer(const void* ptr) const
550                {
551                        const char*const * namePtr = m_nameMap.find(ptr);
552                        if (namePtr && *namePtr)
553                                return *namePtr;
554                        return 0;
555
556                }
557
558                virtual void    registerNameForPointer(const void* ptr, const char* name)
559                {
560                        m_nameMap.insert(ptr,name);
561                }
562
563                virtual void    serializeName(const char* name)
564                {
565                        if (name)
566                        {
567                                //don't serialize name twice
568                                if (findPointer((void*)name))
569                                        return;
570
571                                int len = btStrLen(name);
572                                if (len)
573                                {
574
575                                        int newLen = len+1;
576                                        int padding = ((newLen+3)&~3)-newLen;
577                                        newLen += padding;
578
579                                        //serialize name string now
580                                        btChunk* chunk = allocate(sizeof(char),newLen);
581                                        char* destinationName = (char*)chunk->m_oldPtr;
582                                        for (int i=0;i<len;i++)
583                                        {
584                                                destinationName[i] = name[i];
585                                        }
586                                        destinationName[len] = 0;
587                                        finalizeChunk(chunk,"char",BT_ARRAY_CODE,(void*)name);
588                                }
589                        }
590                }
591
592                virtual int             getSerializationFlags() const
593                {
594                        return m_serializationFlags;
595                }
596
597                virtual void    setSerializationFlags(int flags)
598                {
599                        m_serializationFlags = flags;
600                }
601
602};
603
604
605#endif //BT_SERIALIZER_H
606
Note: See TracBrowser for help on using the repository browser.