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 
132  char *dataPtr = mFileBuffer+mDataStart;
133 
134  bChunkInd dataChunk;
135  dataChunk.code = 0;
136 
137 
138  //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
139  int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
140 
141 
142  if (mFlags &FD_ENDIAN_SWAP)
143  swapLen(dataPtr);
144 
145  //dataPtr += ChunkUtils::getOffset(mFlags);
146  char *dataPtrHead = 0;
147 
148  while (dataChunk.code != DNA1)
149  {
150  if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE) )
151  {
152 
153  // one behind
154  if (dataChunk.code == SDNA) break;
155  //if (dataChunk.code == DNA1) break;
156 
157  // same as (BHEAD+DATA dependency)
158  dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
159  if (dataChunk.dna_nr>=0)
160  {
161  char *id = readStruct(dataPtrHead, dataChunk);
162 
163  // lookup maps
164  if (id)
165  {
166  m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
167  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
168 
169  m_chunks.push_back(dataChunk);
170  // block it
171  //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
172  //if (listID)
173  // listID->push_back((bStructHandle*)id);
174  }
175 
176  if (dataChunk.code == BT_MULTIBODY_CODE)
177  {
179  }
180 
181  if (dataChunk.code == BT_SOFTBODY_CODE)
182  {
184  }
185 
186  if (dataChunk.code == BT_RIGIDBODY_CODE)
187  {
189  }
190 
191  if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
192  {
194  }
195 
196  if (dataChunk.code == BT_CONSTRAINT_CODE)
197  {
199  }
200 
201  if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
202  {
204  }
205 
206  if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
207  {
209  }
210 
211  if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
212  {
214  }
215 
216  if (dataChunk.code == BT_SHAPE_CODE)
217  {
219  }
220 
221  // if (dataChunk.code == GLOB)
222  // {
223  // m_glob = (bStructHandle*) id;
224  // }
225  } else
226  {
227  printf("unknown chunk\n");
228 
229  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
230  }
231  } else
232  {
233  printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
234  }
235 
236 
237  dataPtr += seek;
238  remain-=seek;
239  if (remain<=0)
240  break;
241 
242  seek = getNextBlock(&dataChunk, dataPtr, mFlags);
243  if (mFlags &FD_ENDIAN_SWAP)
244  swapLen(dataPtr);
245 
246  if (seek < 0)
247  break;
248  }
249 
250 }
251 
252 void btBulletFile::addDataBlock(char* dataBlock)
253 {
254  m_dataBlocks.push_back(dataBlock);
255 
256 }
257 
258 
259 
260 
262 {
263 
264  bChunkInd dataChunk;
265  dataChunk.code = DNA1;
266  dataChunk.dna_nr = 0;
267  dataChunk.nr = 1;
268 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
269  if (VOID_IS_8)
270  {
271 #ifdef _WIN64
272  dataChunk.len = sBulletDNAlen64;
273  dataChunk.oldPtr = sBulletDNAstr64;
274  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
275  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
276 #else
277  btAssert(0);
278 #endif
279  }
280  else
281  {
282 #ifndef _WIN64
283  dataChunk.len = sBulletDNAlen;
284  dataChunk.oldPtr = sBulletDNAstr;
285  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
286  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
287 #else//_WIN64
288  btAssert(0);
289 #endif//_WIN64
290  }
291 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
292  if (VOID_IS_8)
293  {
294  dataChunk.len = sBulletDNAlen64;
295  dataChunk.oldPtr = sBulletDNAstr64;
296  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
297  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
298  }
299  else
300  {
301  dataChunk.len = sBulletDNAlen;
302  dataChunk.oldPtr = sBulletDNAstr;
303  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
304  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
305  }
306 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
307 }
308 
309 
310 void btBulletFile::parse(int verboseMode)
311 {
312 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
313  if (VOID_IS_8)
314  {
315 #ifdef _WIN64
316 
317  if (m_DnaCopy)
318  delete m_DnaCopy;
321  parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64);
322 #else
323  btAssert(0);
324 #endif
325  }
326  else
327  {
328 #ifndef _WIN64
329 
330  if (m_DnaCopy)
331  delete m_DnaCopy;
335 #else
336  btAssert(0);
337 #endif
338  }
339 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
340  if (VOID_IS_8)
341  {
342  if (m_DnaCopy)
343  delete m_DnaCopy;
347  }
348  else
349  {
350  if (m_DnaCopy)
351  delete m_DnaCopy;
355  }
356 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
357 
358  //the parsing will convert to cpu endian
360 
361  int littleEndian= 1;
362  littleEndian= ((char*)&littleEndian)[0];
363 
364  mFileBuffer[8] = littleEndian?'v':'V';
365 
366 }
367 
368 // experimental
369 int btBulletFile::write(const char* fileName, bool fixupPointers)
370 {
371  FILE *fp = fopen(fileName, "wb");
372  if (fp)
373  {
374  char header[SIZEOFBLENDERHEADER] ;
375  memcpy(header, m_headerString, 7);
376  int endian= 1;
377  endian= ((char*)&endian)[0];
378 
379  if (endian)
380  {
381  header[7] = '_';
382  } else
383  {
384  header[7] = '-';
385  }
386  if (VOID_IS_8)
387  {
388  header[8]='V';
389  } else
390  {
391  header[8]='v';
392  }
393 
394  header[9] = '2';
395  header[10] = '7';
396  header[11] = '5';
397 
398  fwrite(header,SIZEOFBLENDERHEADER,1,fp);
399 
400  writeChunks(fp, fixupPointers);
401 
402  writeDNA(fp);
403 
404  fclose(fp);
405 
406  } else
407  {
408  printf("Error: cannot open file %s for writing\n",fileName);
409  return 0;
410  }
411  return 1;
412 }
413 
414 
415 
416 void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code)
417 {
418 
419  bParse::bChunkInd dataChunk;
420  dataChunk.code = code;
421  dataChunk.nr = 1;
422  dataChunk.len = len;
423  dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
424  dataChunk.oldPtr = oldPtr;
425 
427  short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr);
428  int elemBytes;
429  elemBytes= mMemoryDNA->getLength(structInfo[0]);
430 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
431  assert(len==elemBytes);
432 
433  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
434  m_chunks.push_back(dataChunk);
435 }
436 
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:1657
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:673
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:202
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:123
#define btAssert(x)
Definition: btScalar.h:113
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:355
#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:269
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
char sBulletDNAstr[]
only the 32bit versions for now
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:348
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1593
#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[]