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_MULTIBODY_CODE)
180  {
182  }
183 
184  if (dataChunk.code == BT_SOFTBODY_CODE)
185  {
187  }
188 
189  if (dataChunk.code == BT_RIGIDBODY_CODE)
190  {
192  }
193 
194  if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
195  {
197  }
198 
199  if (dataChunk.code == BT_CONSTRAINT_CODE)
200  {
202  }
203 
204  if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
205  {
207  }
208 
209  if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
210  {
212  }
213 
214  if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
215  {
217  }
218 
219  if (dataChunk.code == BT_SHAPE_CODE)
220  {
222  }
223 
224  // if (dataChunk.code == GLOB)
225  // {
226  // m_glob = (bStructHandle*) id;
227  // }
228  } else
229  {
230  //printf("unknown chunk\n");
231 
232  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
233  }
234  } else
235  {
236  printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
237  }
238 
239 
240  dataPtr += seek;
241  remain-=seek;
242  if (remain<=0)
243  break;
244 
245  seek = getNextBlock(&dataChunk, dataPtr, mFlags);
246  if (mFlags &FD_ENDIAN_SWAP)
247  swapLen(dataPtr);
248 
249  if (seek < 0)
250  break;
251  }
252 
253 }
254 
255 void btBulletFile::addDataBlock(char* dataBlock)
256 {
257  m_dataBlocks.push_back(dataBlock);
258 
259 }
260 
261 
262 
263 
265 {
266 
267  bChunkInd dataChunk;
268  dataChunk.code = DNA1;
269  dataChunk.dna_nr = 0;
270  dataChunk.nr = 1;
271 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
272  if (VOID_IS_8)
273  {
274 #ifdef _WIN64
275  dataChunk.len = sBulletDNAlen64;
276  dataChunk.oldPtr = sBulletDNAstr64;
277  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
278  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
279 #else
280  btAssert(0);
281 #endif
282  }
283  else
284  {
285 #ifndef _WIN64
286  dataChunk.len = sBulletDNAlen;
287  dataChunk.oldPtr = sBulletDNAstr;
288  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
289  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
290 #else//_WIN64
291  btAssert(0);
292 #endif//_WIN64
293  }
294 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
295  if (VOID_IS_8)
296  {
297  dataChunk.len = sBulletDNAlen64;
298  dataChunk.oldPtr = sBulletDNAstr64;
299  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
300  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
301  }
302  else
303  {
304  dataChunk.len = sBulletDNAlen;
305  dataChunk.oldPtr = sBulletDNAstr;
306  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
307  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
308  }
309 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
310 }
311 
312 
313 void btBulletFile::parse(int verboseMode)
314 {
315 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
316  if (VOID_IS_8)
317  {
318 #ifdef _WIN64
319 
320  if (m_DnaCopy)
321  delete m_DnaCopy;
324  parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64);
325 #else
326  btAssert(0);
327 #endif
328  }
329  else
330  {
331 #ifndef _WIN64
332 
333  if (m_DnaCopy)
334  delete m_DnaCopy;
338 #else
339  btAssert(0);
340 #endif
341  }
342 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
343  if (VOID_IS_8)
344  {
345  if (m_DnaCopy)
346  delete m_DnaCopy;
350  }
351  else
352  {
353  if (m_DnaCopy)
354  delete m_DnaCopy;
358  }
359 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
360 
361  //the parsing will convert to cpu endian
363 
364  int littleEndian= 1;
365  littleEndian= ((char*)&littleEndian)[0];
366 
367  mFileBuffer[8] = littleEndian?'v':'V';
368 
369 }
370 
371 // experimental
372 int btBulletFile::write(const char* fileName, bool fixupPointers)
373 {
374  FILE *fp = fopen(fileName, "wb");
375  if (fp)
376  {
377  char header[SIZEOFBLENDERHEADER] ;
378  memcpy(header, m_headerString, 7);
379  int endian= 1;
380  endian= ((char*)&endian)[0];
381 
382  if (endian)
383  {
384  header[7] = '_';
385  } else
386  {
387  header[7] = '-';
388  }
389  if (VOID_IS_8)
390  {
391  header[8]='V';
392  } else
393  {
394  header[8]='v';
395  }
396 
397  header[9] = '2';
398  header[10] = '7';
399  header[11] = '5';
400 
401  fwrite(header,SIZEOFBLENDERHEADER,1,fp);
402 
403  writeChunks(fp, fixupPointers);
404 
405  writeDNA(fp);
406 
407  fclose(fp);
408 
409  } else
410  {
411  printf("Error: cannot open file %s for writing\n",fileName);
412  return 0;
413  }
414  return 1;
415 }
416 
417 
418 
419 void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code)
420 {
421 
422  bParse::bChunkInd dataChunk;
423  dataChunk.code = code;
424  dataChunk.nr = 1;
425  dataChunk.len = len;
426  dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
427  dataChunk.oldPtr = oldPtr;
428 
430  short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr);
431  int elemBytes;
432  elemBytes= mMemoryDNA->getLength(structInfo[0]);
433 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
434  assert(len==elemBytes);
435 
436  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
437  m_chunks.push_back(dataChunk);
438 }
439 
bParse::bDNA::getLength
short getLength(int ind)
Definition: bDNA.cpp:74
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:48
bParse::bFile
Definition: bFile.h:48
BT_TRIANLGE_INFO_MAP
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:124
bParse::ChunkUtils::getOffset
static int getOffset(int flags)
Definition: bChunk.cpp:51
bParse::bStructHandle
Definition: bCommon.h:33
bParse::bChunkInd::oldPtr
void * oldPtr
Definition: bChunk.h:67
sBulletDNAstr
char sBulletDNAstr[]
Definition: btSerializer.cpp:1
bParse::btBulletFile::m_bvhs
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:54
bParse::bDNA::getReverseType
int getReverseType(short type)
Definition: bDNA.cpp:82
bParse::btBulletFile::m_multiBodies
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:42
BT_DYNAMICSWORLD_CODE
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:129
bParse::bFile::swapLen
void swapLen(char *dataPtr)
Definition: bFile.cpp:356
bParse::btBulletFile::btBulletFile
btBulletFile()
Definition: btBulletFile.cpp:46
bParse::bDNA
Definition: bDNA.h:32
BT_SHAPE_CODE
#define BT_SHAPE_CODE
Definition: btSerializer.h:125
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:47
bParse::bChunkInd::nr
int nr
Definition: bChunk.h:68
bParse::bFile::readStruct
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:657
bParse::btBulletFile::parseData
virtual void parseData()
Definition: btBulletFile.cpp:115
BT_MULTIBODY_CODE
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:117
bParse::btBulletFile::m_rigidBodies
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:46
bParse::bFile::mFileLen
int mFileLen
Definition: bFile.h:56
bParse::btBulletFile::m_dynamicsWorldInfo
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:58
bParse::FD_BROKEN_DNA
@ FD_BROKEN_DNA
Definition: bFile.h:36
sBulletDNAstr64
char sBulletDNAstr64[]
Definition: btSerializer64.cpp:1
BT_COLLISIONOBJECT_CODE
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:119
bParse::btBulletFile::write
virtual int write(const char *fileName, bool fixupPointers=false)
Definition: btBulletFile.cpp:372
bParse::btBulletFile::m_collisionShapes
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:50
bParse::btBulletFile::addDataBlock
virtual void addDataBlock(char *dataBlock)
Definition: btBulletFile.cpp:255
BT_SOFTBODY_CODE
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:118
SIZEOFBLENDERHEADER
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:24
btAssert
#define btAssert(x)
Definition: btScalar.h:131
bParse::bFile::getNextBlock
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1641
btBulletFile.h
bParse::bFile::mFlags
int mFlags
Definition: bFile.h:77
bParse::bFile::mMemoryDNA
bDNA * mMemoryDNA
Definition: bFile.h:64
bParse::bFile::m_chunks
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:69
bParse::btBulletFile::m_triangleInfoMaps
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:56
bParse::bFile::parseInternal
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:203
BT_CONSTRAINT_CODE
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:121
bParse::bChunkInd
Definition: bChunk.h:62
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:199
BT_QUANTIZED_BVH_CODE
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:123
bParse::VOID_IS_8
const bool VOID_IS_8
Definition: bChunk.h:89
bParse::bFile::mFileBuffer
char * mFileBuffer
Definition: bFile.h:55
bParse::FD_ENDIAN_SWAP
@ FD_ENDIAN_SWAP
Definition: bFile.h:31
bParse::btBulletFile::~btBulletFile
virtual ~btBulletFile()
Definition: btBulletFile.cpp:97
bDNA.h
bParse::bChunkInd::code
int code
Definition: bChunk.h:66
bParse::bChunkInd::len
int len
Definition: bChunk.h:66
bParse::btBulletFile::m_dataBlocks
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:60
SDNA
#define SDNA
Definition: bDefines.h:111
btHashMap::insert
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:274
bParse::btBulletFile::writeDNA
virtual void writeDNA(FILE *fp)
Definition: btBulletFile.cpp:264
bParse::btBulletFile::m_constraints
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:52
bParse::btBulletFile::parse
virtual void parse(int verboseMode)
Definition: btBulletFile.cpp:313
bParse::bFile::mDataStart
int mDataStart
Definition: bFile.h:62
bParse::bDNA::init
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:349
bParse::btBulletFile::m_DnaCopy
char * m_DnaCopy
Definition: btBulletFile.h:38
bParse::bFile::mLibPointers
bPtrMap mLibPointers
Definition: bFile.h:60
bParse::bDNA::getStruct
short * getStruct(int ind)
Definition: bDNA.cpp:66
bParse
Definition: btBulletWorldImporter.h:29
bParse::bFile::m_chunkPtrPtrMap
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:70
bParse::btBulletFile::addStruct
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
Definition: btBulletFile.cpp:419
bParse::btBulletFile::m_collisionObjects
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:48
BT_RIGIDBODY_CODE
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:120
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:274
sBulletDNAlen64
int sBulletDNAlen64
Definition: btSerializer64.cpp:599
bParse::bChunkInd::dna_nr
int dna_nr
Definition: bChunk.h:68
bParse::bFile::writeChunks
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1577
bParse::btBulletFile::m_softBodies
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:44
DNA1
#define DNA1
Definition: bDefines.h:107
bParse::bFile::m_headerString
char m_headerString[7]
Definition: bFile.h:52
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:155
bDefines.h
sBulletDNAlen
int sBulletDNAlen
Definition: btSerializer.cpp:599