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