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 
void push_back(const T &_Val)
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:60
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1641
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:56
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:121
int sBulletDNAlen64
bDNA * mMemoryDNA
Definition: bFile.h:64
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:52
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:117
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:123
#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:48
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:118
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:129
#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
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:274
int mFlags
Definition: bFile.h:77
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:44
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:119
int mFileLen
Definition: bFile.h:56
int size() const
return the number of elements in the array
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:54
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:42
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:120
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:69
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:50
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:124
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:58
char m_headerString[7]
Definition: bFile.h:52
#define BT_SHAPE_CODE
Definition: btSerializer.h:125
virtual void parseData()
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:46
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[]