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  mDataStart = 12;
127 
128  char *dataPtr = mFileBuffer+mDataStart;
129 
130  bChunkInd dataChunk;
131  dataChunk.code = 0;
132 
133 
134  //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
135  int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
136 
137 
138  if (mFlags &FD_ENDIAN_SWAP)
139  swapLen(dataPtr);
140 
141  //dataPtr += ChunkUtils::getOffset(mFlags);
142  char *dataPtrHead = 0;
143 
144  while (dataChunk.code != DNA1)
145  {
146  if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE) )
147  {
148 
149  // one behind
150  if (dataChunk.code == SDNA) break;
151  //if (dataChunk.code == DNA1) break;
152 
153  // same as (BHEAD+DATA dependency)
154  dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
155  if (dataChunk.dna_nr>=0)
156  {
157  char *id = readStruct(dataPtrHead, dataChunk);
158 
159  // lookup maps
160  if (id)
161  {
162  m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
163  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
164 
165  m_chunks.push_back(dataChunk);
166  // block it
167  //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
168  //if (listID)
169  // listID->push_back((bStructHandle*)id);
170  }
171 
172  if (dataChunk.code == BT_SOFTBODY_CODE)
173  {
175  }
176 
177  if (dataChunk.code == BT_RIGIDBODY_CODE)
178  {
180  }
181 
182  if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
183  {
185  }
186 
187  if (dataChunk.code == BT_CONSTRAINT_CODE)
188  {
190  }
191 
192  if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
193  {
195  }
196 
197  if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
198  {
200  }
201 
202  if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
203  {
205  }
206 
207  if (dataChunk.code == BT_SHAPE_CODE)
208  {
210  }
211 
212  // if (dataChunk.code == GLOB)
213  // {
214  // m_glob = (bStructHandle*) id;
215  // }
216  } else
217  {
218  printf("unknown chunk\n");
219 
220  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
221  }
222  } else
223  {
224  printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
225  }
226 
227 
228  dataPtr += seek;
229 
230  seek = getNextBlock(&dataChunk, dataPtr, mFlags);
231  if (mFlags &FD_ENDIAN_SWAP)
232  swapLen(dataPtr);
233 
234  if (seek < 0)
235  break;
236  }
237 
238 }
239 
240 void btBulletFile::addDataBlock(char* dataBlock)
241 {
242  m_dataBlocks.push_back(dataBlock);
243 
244 }
245 
246 
247 
248 
250 {
251 
252  bChunkInd dataChunk;
253  dataChunk.code = DNA1;
254  dataChunk.dna_nr = 0;
255  dataChunk.nr = 1;
256 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
257  if (VOID_IS_8)
258  {
259 #ifdef _WIN64
260  dataChunk.len = sBulletDNAlen64;
261  dataChunk.oldPtr = sBulletDNAstr64;
262  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
263  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
264 #else
265  btAssert(0);
266 #endif
267  }
268  else
269  {
270 #ifndef _WIN64
271  dataChunk.len = sBulletDNAlen;
272  dataChunk.oldPtr = sBulletDNAstr;
273  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
274  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
275 #else//_WIN64
276  btAssert(0);
277 #endif//_WIN64
278  }
279 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
280  if (VOID_IS_8)
281  {
282  dataChunk.len = sBulletDNAlen64;
283  dataChunk.oldPtr = sBulletDNAstr64;
284  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
285  fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
286  }
287  else
288  {
289  dataChunk.len = sBulletDNAlen;
290  dataChunk.oldPtr = sBulletDNAstr;
291  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
292  fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
293  }
294 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
295 }
296 
297 
298 void btBulletFile::parse(int verboseMode)
299 {
300 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
301  if (VOID_IS_8)
302  {
303 #ifdef _WIN64
304 
305  if (m_DnaCopy)
306  delete m_DnaCopy;
309  parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64);
310 #else
311  btAssert(0);
312 #endif
313  }
314  else
315  {
316 #ifndef _WIN64
317 
318  if (m_DnaCopy)
319  delete m_DnaCopy;
323 #else
324  btAssert(0);
325 #endif
326  }
327 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
328  if (VOID_IS_8)
329  {
330  if (m_DnaCopy)
331  delete m_DnaCopy;
335  }
336  else
337  {
338  if (m_DnaCopy)
339  delete m_DnaCopy;
343  }
344 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
345 
346  //the parsing will convert to cpu endian
348 
349  int littleEndian= 1;
350  littleEndian= ((char*)&littleEndian)[0];
351 
352  mFileBuffer[8] = littleEndian?'v':'V';
353 
354 }
355 
356 // experimental
357 int btBulletFile::write(const char* fileName, bool fixupPointers)
358 {
359  FILE *fp = fopen(fileName, "wb");
360  if (fp)
361  {
362  char header[SIZEOFBLENDERHEADER] ;
363  memcpy(header, m_headerString, 7);
364  int endian= 1;
365  endian= ((char*)&endian)[0];
366 
367  if (endian)
368  {
369  header[7] = '_';
370  } else
371  {
372  header[7] = '-';
373  }
374  if (VOID_IS_8)
375  {
376  header[8]='V';
377  } else
378  {
379  header[8]='v';
380  }
381 
382  header[9] = '2';
383  header[10] = '7';
384  header[11] = '5';
385 
386  fwrite(header,SIZEOFBLENDERHEADER,1,fp);
387 
388  writeChunks(fp, fixupPointers);
389 
390  writeDNA(fp);
391 
392  fclose(fp);
393 
394  } else
395  {
396  printf("Error: cannot open file %s for writing\n",fileName);
397  return 0;
398  }
399  return 1;
400 }
401 
402 
403 
404 void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code)
405 {
406 
407  bParse::bChunkInd dataChunk;
408  dataChunk.code = code;
409  dataChunk.nr = 1;
410  dataChunk.len = len;
411  dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
412  dataChunk.oldPtr = oldPtr;
413 
415  short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr);
416  int elemBytes;
417  elemBytes= mMemoryDNA->getLength(structInfo[0]);
418 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
419  assert(len==elemBytes);
420 
421  mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
422  m_chunks.push_back(dataChunk);
423 }
void push_back(const T &_Val)
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:57
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1639
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:53
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:119
int sBulletDNAlen64
bDNA * mMemoryDNA
Definition: bFile.h:63
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:49
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:655
void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:191
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:121
#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:54
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:45
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:116
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:127
#define SDNA
Definition: bDefines.h:112
virtual void writeDNA(FILE *fp)
void swapLen(char *dataPtr)
Definition: bFile.cpp:337
#define DNA1
Definition: bDefines.h:108
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:269
int mFlags
Definition: bFile.h:76
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:41
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:117
int size() const
return the number of elements in the array
char sBulletDNAstr[]
only the 32bit versions for now
Definition: btSerializer.cpp:1
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:24
int mDataStart
Definition: bFile.h:61
virtual int write(const char *fileName, bool fixupPointers=false)
virtual void addDataBlock(char *dataBlock)
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:51
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:118
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:68
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:47
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:1575
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:122
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:55
char m_headerString[7]
Definition: bFile.h:51
#define BT_SHAPE_CODE
Definition: btSerializer.h:123
virtual void parseData()
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:43
bPtrMap mLibPointers
Definition: bFile.h:59
int getReverseType(short type)
Definition: bDNA.cpp:82
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:69
short getLength(int ind)
Definition: bDNA.cpp:74
static int getOffset(int flags)
Definition: bChunk.cpp:51
char sBulletDNAstr64[]