Bullet Collision Detection & Physics Library: btBulletFile.cpp Source File

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
46 btBulletFile::btBulletFile()
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
56 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
57 memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
58 mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64);
59 #else//_WIN64
60 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
61 memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
62 mMemoryDNA->init(m_DnaCopy,sBulletDNAlen);
63 #endif//_WIN64
64 #else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
65 if (VOID_IS_8)
66 {
67 m_DnaCopy = (char*) btAlignedAlloc(sBulletDNAlen64,16);
68 memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
69 mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64);
70 }
71 else
72 {
73 m_DnaCopy =(char*) btAlignedAlloc(sBulletDNAlen,16);
74 memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
75 mMemoryDNA->init(m_DnaCopy,sBulletDNAlen);
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
97 btBulletFile::~btBulletFile()
98 {
99 if (m_DnaCopy)
100 btAlignedFree(m_DnaCopy);
101
102
103 while (m_dataBlocks.size())
104 {
105 char* dataBlock = m_dataBlocks[m_dataBlocks.size()-1];
106 delete[] dataBlock;
107 m_dataBlocks.pop_back();
108 }
109
110 }
111
112
113
114 // ----------------------------------------------------- //
115 void btBulletFile::parseData()
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 {
181 m_multiBodies.push_back((bStructHandle*)id);
182 }
183
184 if (dataChunk.code == BT_SOFTBODY_CODE)
185 {
186 m_softBodies.push_back((bStructHandle*) id);
187 }
188
189 if (dataChunk.code == BT_RIGIDBODY_CODE)
190 {
191 m_rigidBodies.push_back((bStructHandle*) id);
192 }
193
194 if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
195 {
196 m_dynamicsWorldInfo.push_back((bStructHandle*) id);
197 }
198
199 if (dataChunk.code == BT_CONSTRAINT_CODE)
200 {
201 m_constraints.push_back((bStructHandle*) id);
202 }
203
204 if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
205 {
206 m_bvhs.push_back((bStructHandle*) id);
207 }
208
209 if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
210 {
211 m_triangleInfoMaps.push_back((bStructHandle*) id);
212 }
213
214 if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
215 {
216 m_collisionObjects.push_back((bStructHandle*) id);
217 }
218
219 if (dataChunk.code == BT_SHAPE_CODE)
220 {
221 m_collisionShapes.push_back((bStructHandle*) id);
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
264 void btBulletFile::writeDNA(FILE* fp)
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;
322 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
323 memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
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;
335 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
336 memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
337 parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
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;
347 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
348 memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
349 parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen64);
350 }
351 else
352 {
353 if (m_DnaCopy)
354 delete m_DnaCopy;
355 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
356 memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
357 parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
358 }
359 #endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
360
361 //the parsing will convert to cpu endian
362 mFlags &=~FD_ENDIAN_SWAP;
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
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:274
bDNA.h
bParse::btBulletFile::m_dataBlocks
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:60
bParse::bFile::getNextBlock
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1641
bParse::btBulletFile::m_triangleInfoMaps
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:56
BT_CONSTRAINT_CODE
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:121
sBulletDNAlen64
int sBulletDNAlen64
Definition: btSerializer64.cpp:599
bParse::bChunkInd::nr
int nr
Definition: bChunk.h:68
bParse::bFile
Definition: bFile.h:48
bParse::bFile::mMemoryDNA
bDNA * mMemoryDNA
Definition: bFile.h:64
bParse::btBulletFile::m_constraints
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:52
BT_MULTIBODY_CODE
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:117
bParse::bFile::readStruct
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:657
bParse::bFile::parseInternal
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:203
BT_QUANTIZED_BVH_CODE
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:123
bParse::btBulletFile::m_DnaCopy
char * m_DnaCopy
Definition: btBulletFile.h:38
btBulletFile.h
bParse::bChunkInd::len
int len
Definition: bChunk.h:66
bParse::bChunkInd
Definition: bChunk.h:62
btAssert
#define btAssert(x)
Definition: btScalar.h:131
bParse::btBulletFile::addStruct
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
Definition: btBulletFile.cpp:419
bParse::bFile::mFileBuffer
char * mFileBuffer
Definition: bFile.h:55
bParse::btBulletFile::m_collisionObjects
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:48
BT_SOFTBODY_CODE
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:118
BT_DYNAMICSWORLD_CODE
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:129
bParse::bChunkInd::dna_nr
int dna_nr
Definition: bChunk.h:68
SDNA
#define SDNA
Definition: bDefines.h:111
bParse::btBulletFile::writeDNA
virtual void writeDNA(FILE *fp)
Definition: btBulletFile.cpp:264
bParse::FD_BROKEN_DNA
Definition: bFile.h:36
bParse::bFile::swapLen
void swapLen(char *dataPtr)
Definition: bFile.cpp:356
bParse::bStructHandle
Definition: bCommon.h:33
DNA1
#define DNA1
Definition: bDefines.h:107
sBulletDNAlen
int sBulletDNAlen
Definition: btSerializer.cpp:599
bParse::FD_ENDIAN_SWAP
Definition: bFile.h:31
bParse::btBulletFile::parse
virtual void parse(int verboseMode)
Definition: btBulletFile.cpp:313
bParse::bChunkInd::oldPtr
void * oldPtr
Definition: bChunk.h:67
bParse::VOID_IS_8
const bool VOID_IS_8
Definition: bChunk.h:89
bParse::bChunkInd::code
int code
Definition: bChunk.h:66
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:48
btHashMap::insert
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:274
bParse::bFile::mFlags
int mFlags
Definition: bFile.h:77
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:199
bParse::btBulletFile::m_softBodies
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:44
BT_COLLISIONOBJECT_CODE
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:119
bParse::bFile::mFileLen
int mFileLen
Definition: bFile.h:56
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:155
sBulletDNAstr
char sBulletDNAstr[]
Definition: btSerializer.cpp:1
SIZEOFBLENDERHEADER
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:24
bParse::btBulletFile::btBulletFile
btBulletFile()
Definition: btBulletFile.cpp:46
bParse::bFile::mDataStart
int mDataStart
Definition: bFile.h:62
bParse::btBulletFile::write
virtual int write(const char *fileName, bool fixupPointers=false)
Definition: btBulletFile.cpp:372
bParse::btBulletFile::addDataBlock
virtual void addDataBlock(char *dataBlock)
Definition: btBulletFile.cpp:255
bParse::btBulletFile::m_bvhs
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:54
bParse::btBulletFile::m_multiBodies
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:42
BT_RIGIDBODY_CODE
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:120
bParse::bFile::m_chunks
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:69
bParse
Definition: btBulletWorldImporter.h:29
bParse::btBulletFile::m_collisionShapes
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:50
bParse::bDNA
Definition: bDNA.h:32
bParse::bDNA::getStruct
short * getStruct(int ind)
Definition: bDNA.cpp:66
bDefines.h
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:47
bParse::bDNA::init
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:349
bParse::bFile::writeChunks
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1577
BT_TRIANLGE_INFO_MAP
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:124
bParse::btBulletFile::m_dynamicsWorldInfo
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:58
bParse::bFile::m_headerString
char m_headerString[7]
Definition: bFile.h:52
BT_SHAPE_CODE
#define BT_SHAPE_CODE
Definition: btSerializer.h:125
bParse::btBulletFile::parseData
virtual void parseData()
Definition: btBulletFile.cpp:115
bParse::btBulletFile::m_rigidBodies
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:46
bParse::bFile::mLibPointers
bPtrMap mLibPointers
Definition: bFile.h:60
bParse::bDNA::getReverseType
int getReverseType(short type)
Definition: bDNA.cpp:82
bParse::bFile::m_chunkPtrPtrMap
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:70
bParse::btBulletFile::~btBulletFile
virtual ~btBulletFile()
Definition: btBulletFile.cpp:97
bParse::bDNA::getLength
short getLength(int ind)
Definition: bDNA.cpp:74
bParse::ChunkUtils::getOffset
static int getOffset(int flags)
Definition: bChunk.cpp:51
sBulletDNAstr64
char sBulletDNAstr64[]
Definition: btSerializer64.cpp:1