Bullet Collision Detection & Physics Library
btBulletFile.cpp
Go to the documentation of this file.
1 /*
2 bParse
3 Copyright (c) 2006-2010 Erwin Coumans http://gamekit.googlecode.com
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 #include "btBulletFile.h"
17 #include "bDefines.h"
18 #include "bDNA.h"
19 
20 #if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
21 #include <memory.h>
22 #endif
23 #include <string.h>
24 
25 
26 // 32 && 64 bit versions
27 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
28 #ifdef _WIN64
29 extern char sBulletDNAstr64[];
30 extern int sBulletDNAlen64;
31 #else
32 extern char sBulletDNAstr[];
33 extern int sBulletDNAlen;
34 #endif //_WIN64
35 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
36 
37 extern char sBulletDNAstr64[];
38 extern int sBulletDNAlen64;
39 extern char sBulletDNAstr[];
40 extern int sBulletDNAlen;
41 
42 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
43 
44 using namespace bParse;
45 
47 :bFile("", "BULLET ")
48 {
49  mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it"
50 
51  m_DnaCopy = 0;
52 
53 
54 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
55 #ifdef _WIN64
59 #else//_WIN64
63 #endif//_WIN64
64 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
65  if (VOID_IS_8)
66  {
70  }
71  else
72  {
76  }
77 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
78 }
79 
80 
81 
82 btBulletFile::btBulletFile(const char* fileName)
83 :bFile(fileName, "BULLET ")
84 {
85  m_DnaCopy = 0;
86 }
87 
88 
89 
90 btBulletFile::btBulletFile(char *memoryBuffer, int len)
91 :bFile(memoryBuffer,len, "BULLET ")
92 {
93  m_DnaCopy = 0;
94 }
95 
96 
98 {
99  if (m_DnaCopy)
101 
102 
103  while (m_dataBlocks.size())
104  {
105  char* dataBlock = m_dataBlocks[m_dataBlocks.size()-1];
106  delete[] dataBlock;
108  }
109 
110 }
111 
112 
113 
114 // ----------------------------------------------------- //
116 {
117 // printf ("Building datablocks");
118 // printf ("Chunk size = %d",CHUNK_HEADER_LEN);
119 // printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
120 
121  const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
122 
123  //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
124 
125 
126  int remain = mFileLen;
127 
128  mDataStart = 12;
129  remain-=12;
130 
131  //invalid/empty file?
132  if (remain < sizeof(bChunkInd))
133  return;
134 
135  char *dataPtr = mFileBuffer+mDataStart;
136 
137  bChunkInd dataChunk;
138  dataChunk.code = 0;
139 
140 
141  //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
142  int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
143 
144 
145  if (mFlags &FD_ENDIAN_SWAP)
146  swapLen(dataPtr);
147 
148  //dataPtr += ChunkUtils::getOffset(mFlags);
149  char *dataPtrHead = 0;
150 
151  while (dataChunk.code != DNA1)
152  {
153  if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE) )
154  {
155 
156  // one behind
157  if (dataChunk.code == SDNA) break;
158  //if (dataChunk.code == DNA1) break;
159 
160  // same as (BHEAD+DATA dependency)
161  dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
162  if (dataChunk.dna_nr>=0)
163  {
164  char *id = readStruct(dataPtrHead, dataChunk);
165 
166  // lookup maps
167  if (id)
168  {
169  m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
170  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
171 
172  m_chunks.push_back(dataChunk);
173  // block it
174  //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
175  //if (listID)
176  // listID->push_back((bStructHandle*)id);
177  }
178 
179  if (dataChunk.code == BT_CONTACTMANIFOLD_CODE)
180  {
182  }
183  if (dataChunk.code == BT_MULTIBODY_CODE)
184  {
186  }
187 
188  if (dataChunk.code == BT_MB_LINKCOLLIDER_CODE)
189  {
191  }
192 
193  if (dataChunk.code == BT_SOFTBODY_CODE)
194  {
196  }
197 
198  if (dataChunk.code == BT_RIGIDBODY_CODE)
199  {
201  }
202 
203  if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
204  {
206  }
207 
208  if (dataChunk.code == BT_CONSTRAINT_CODE)
209  {
211  }
212 
213  if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
214  {
216  }
217 
218  if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
219  {
221  }
222 
223  if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
224  {
226  }
227 
228  if (dataChunk.code == BT_SHAPE_CODE)
229  {
231  }
232 
233  // if (dataChunk.code == GLOB)
234  // {
235  // m_glob = (bStructHandle*) id;
236  // }
237  } else
238  {
239  //printf("unknown chunk\n");
240 
241  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
242  }
243  } else
244  {
245  printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
246  }
247 
248 
249  dataPtr += seek;
250  remain-=seek;
251  if (remain<=0)
252  break;
253 
254  seek = getNextBlock(&dataChunk, dataPtr, mFlags);
255  if (mFlags &FD_ENDIAN_SWAP)
256  swapLen(dataPtr);
257 
258  if (seek < 0)
259  break;
260  }
261 
262 }
263 
264 void btBulletFile::addDataBlock(char* dataBlock)
265 {
266  m_dataBlocks.push_back(dataBlock);
267 
268 }
269 
270 
271 
272 
274 {
275 
276  bChunkInd dataChunk;
277  dataChunk.code = DNA1;
278  dataChunk.dna_nr = 0;
279  dataChunk.nr = 1;
280 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
281  if (VOID_IS_8)
282  {
283 #ifdef _WIN64
284  dataChunk.len = sBulletDNAlen64;
285  dataChunk.oldPtr = sBulletDNAstr64;
286  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
287  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
288 #else
289  btAssert(0);
290 #endif
291  }
292  else
293  {
294 #ifndef _WIN64
295  dataChunk.len = sBulletDNAlen;
296  dataChunk.oldPtr = sBulletDNAstr;
297  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
298  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
299 #else//_WIN64
300  btAssert(0);
301 #endif//_WIN64
302  }
303 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
304  if (VOID_IS_8)
305  {
306  dataChunk.len = sBulletDNAlen64;
307  dataChunk.oldPtr = sBulletDNAstr64;
308  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
309  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
310  }
311  else
312  {
313  dataChunk.len = sBulletDNAlen;
314  dataChunk.oldPtr = sBulletDNAstr;
315  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
316  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
317  }
318 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
319 }
320 
321 
322 void btBulletFile::parse(int verboseMode)
323 {
324 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
325  if (VOID_IS_8)
326  {
327 #ifdef _WIN64
328 
329  if (m_DnaCopy)
330  delete m_DnaCopy;
333  parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64);
334 #else
335  btAssert(0);
336 #endif
337  }
338  else
339  {
340 #ifndef _WIN64
341 
342  if (m_DnaCopy)
343  delete m_DnaCopy;
347 #else
348  btAssert(0);
349 #endif
350  }
351 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
352  if (VOID_IS_8)
353  {
354  if (m_DnaCopy)
355  delete m_DnaCopy;
359  }
360  else
361  {
362  if (m_DnaCopy)
363  delete m_DnaCopy;
367  }
368 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
369 
370  //the parsing will convert to cpu endian
372 
373  int littleEndian= 1;
374  littleEndian= ((char*)&littleEndian)[0];
375 
376  mFileBuffer[8] = littleEndian?'v':'V';
377 
378 }
379 
380 // experimental
381 int btBulletFile::write(const char* fileName, bool fixupPointers)
382 {
383  FILE *fp = fopen(fileName, "wb");
384  if (fp)
385  {
386  char header[SIZEOFBLENDERHEADER] ;
387  memcpy(header, m_headerString, 7);
388  int endian= 1;
389  endian= ((char*)&endian)[0];
390 
391  if (endian)
392  {
393  header[7] = '_';
394  } else
395  {
396  header[7] = '-';
397  }
398  if (VOID_IS_8)
399  {
400  header[8]='V';
401  } else
402  {
403  header[8]='v';
404  }
405 
406  header[9] = '2';
407  header[10] = '7';
408  header[11] = '5';
409 
410  fwrite(header,SIZEOFBLENDERHEADER,1,fp);
411 
412  writeChunks(fp, fixupPointers);
413 
414  writeDNA(fp);
415 
416  fclose(fp);
417 
418  } else
419  {
420  printf("Error: cannot open file %s for writing\n",fileName);
421  return 0;
422  }
423  return 1;
424 }
425 
426 
427 
428 void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code)
429 {
430 
431  bParse::bChunkInd dataChunk;
432  dataChunk.code = code;
433  dataChunk.nr = 1;
434  dataChunk.len = len;
435  dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
436  dataChunk.oldPtr = oldPtr;
437 
439  short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr);
440  int elemBytes;
441  elemBytes= mMemoryDNA->getLength(structInfo[0]);
442 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
443  assert(len==elemBytes);
444 
445  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
446  m_chunks.push_back(dataChunk);
447 }
448 
btAlignedObjectArray< bStructHandle * > m_contactManifolds
Definition: btBulletFile.h:62
void push_back(const T &_Val)
#define BT_CONTACTMANIFOLD_CODE
Definition: btSerializer.h:132
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:64
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1641
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:58
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:123
int sBulletDNAlen64
bDNA * mMemoryDNA
Definition: bFile.h:64
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:54
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:118
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:657
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:203
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:125
#define BT_MB_LINKCOLLIDER_CODE
Definition: btSerializer.h:119
#define btAssert(x)
Definition: btScalar.h:131
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
char * mFileBuffer
Definition: bFile.h:55
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:50
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:120
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:131
#define SDNA
Definition: bDefines.h:111
virtual void writeDNA(FILE *fp)
void swapLen(char *dataPtr)
Definition: bFile.cpp:356
#define DNA1
Definition: bDefines.h:107
int sBulletDNAlen
int size() const
return the number of elements in the array
virtual void parse(int verboseMode)
void * oldPtr
Definition: bChunk.h:67
const bool VOID_IS_8
Definition: bChunk.h:89
#define btAlignedFree(ptr)
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:262
int mFlags
Definition: bFile.h:77
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:46
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:121
btAlignedObjectArray< bStructHandle * > m_multiBodyLinkColliders
Definition: btBulletFile.h:44
int mFileLen
Definition: bFile.h:56
char sBulletDNAstr[]
Definition: btSerializer.cpp:1
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:24
int mDataStart
Definition: bFile.h:62
virtual int write(const char *fileName, bool fixupPointers=false)
virtual void addDataBlock(char *dataBlock)
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:56
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:42
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:122
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:69
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:52
short * getStruct(int ind)
Definition: bDNA.cpp:66
#define btAlignedAlloc(size, alignment)
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:349
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1577
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:126
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:60
char m_headerString[7]
Definition: bFile.h:52
#define BT_SHAPE_CODE
Definition: btSerializer.h:127
virtual void parseData()
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:48
bPtrMap mLibPointers
Definition: bFile.h:60
int getReverseType(short type)
Definition: bDNA.cpp:82
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:70
short getLength(int ind)
Definition: bDNA.cpp:74
static int getOffset(int flags)
Definition: bChunk.cpp:51
char sBulletDNAstr64[]