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 // 32 && 64 bit versions
26 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
27 #ifdef _WIN64
28 extern char sBulletDNAstr64[];
29 extern int sBulletDNAlen64;
30 #else
31 extern char sBulletDNAstr[];
32 extern int sBulletDNAlen;
33 #endif //_WIN64
34 #else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
35
36 extern char sBulletDNAstr64[];
37 extern int sBulletDNAlen64;
38 extern char sBulletDNAstr[];
39 extern int sBulletDNAlen;
40
41 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
42
43 using namespace bParse;
44
45 btBulletFile::btBulletFile()
46 : bFile("", "BULLET ")
47 {
48 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"
49
50 m_DnaCopy = 0;
51
52 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
53 #ifdef _WIN64
54 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
55 memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
56 mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64);
57 #else //_WIN64
58 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
59 memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
60 mMemoryDNA->init(m_DnaCopy, sBulletDNAlen);
61 #endif //_WIN64
62 #else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
63 if (VOID_IS_8)
64 {
65 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
66 memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
67 mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64);
68 }
69 else
70 {
71 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
72 memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
73 mMemoryDNA->init(m_DnaCopy, sBulletDNAlen);
74 }
75 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
76 }
77
78 btBulletFile::btBulletFile(const char* fileName)
79 : bFile(fileName, "BULLET ")
80 {
81 m_DnaCopy = 0;
82 }
83
84 btBulletFile::btBulletFile(char* memoryBuffer, int len)
85 : bFile(memoryBuffer, len, "BULLET ")
86 {
87 m_DnaCopy = 0;
88 }
89
90 btBulletFile::~btBulletFile()
91 {
92 if (m_DnaCopy)
93 btAlignedFree(m_DnaCopy);
94
95 while (m_dataBlocks.size())
96 {
97 char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1];
98 delete[] dataBlock;
99 m_dataBlocks.pop_back();
100 }
101 }
102
103 // ----------------------------------------------------- //
104 void btBulletFile::parseData()
105 {
106 // printf ("Building datablocks");
107 // printf ("Chunk size = %d",CHUNK_HEADER_LEN);
108 // printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
109
110 const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0;
111
112 //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
113
114 int remain = mFileLen;
115
116 mDataStart = 12;
117 remain -= 12;
118
119 //invalid/empty file?
120 if (remain < sizeof(bChunkInd))
121 return;
122
123 char* dataPtr = mFileBuffer + mDataStart;
124
125 bChunkInd dataChunk;
126 dataChunk.code = 0;
127
128 //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
129 int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
130
131 if (mFlags & FD_ENDIAN_SWAP)
132 swapLen(dataPtr);
133
134 //dataPtr += ChunkUtils::getOffset(mFlags);
135 char* dataPtrHead = 0;
136
137 while (dataChunk.code != DNA1)
138 {
139 if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE))
140 {
141 // one behind
142 if (dataChunk.code == SDNA) break;
143 //if (dataChunk.code == DNA1) break;
144
145 // same as (BHEAD+DATA dependency)
146 dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags);
147 if (dataChunk.dna_nr >= 0)
148 {
149 char* id = readStruct(dataPtrHead, dataChunk);
150
151 // lookup maps
152 if (id)
153 {
154 m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
155 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
156
157 m_chunks.push_back(dataChunk);
158 // block it
159 //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
160 //if (listID)
161 // listID->push_back((bStructHandle*)id);
162 }
163
164 if (dataChunk.code == BT_CONTACTMANIFOLD_CODE)
165 {
166 m_contactManifolds.push_back((bStructHandle*)id);
167 }
168 if (dataChunk.code == BT_MULTIBODY_CODE)
169 {
170 m_multiBodies.push_back((bStructHandle*)id);
171 }
172
173 if (dataChunk.code == BT_MB_LINKCOLLIDER_CODE)
174 {
175 m_multiBodyLinkColliders.push_back((bStructHandle*)id);
176 }
177
178 if (dataChunk.code == BT_SOFTBODY_CODE)
179 {
180 m_softBodies.push_back((bStructHandle*)id);
181 }
182
183 if (dataChunk.code == BT_RIGIDBODY_CODE)
184 {
185 m_rigidBodies.push_back((bStructHandle*)id);
186 }
187
188 if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
189 {
190 m_dynamicsWorldInfo.push_back((bStructHandle*)id);
191 }
192
193 if (dataChunk.code == BT_CONSTRAINT_CODE)
194 {
195 m_constraints.push_back((bStructHandle*)id);
196 }
197
198 if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
199 {
200 m_bvhs.push_back((bStructHandle*)id);
201 }
202
203 if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
204 {
205 m_triangleInfoMaps.push_back((bStructHandle*)id);
206 }
207
208 if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
209 {
210 m_collisionObjects.push_back((bStructHandle*)id);
211 }
212
213 if (dataChunk.code == BT_SHAPE_CODE)
214 {
215 m_collisionShapes.push_back((bStructHandle*)id);
216 }
217
218 // if (dataChunk.code == GLOB)
219 // {
220 // m_glob = (bStructHandle*) id;
221 // }
222 }
223 else
224 {
225 //printf("unknown chunk\n");
226
227 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
228 }
229 }
230 else
231 {
232 printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
233 }
234
235 dataPtr += seek;
236 remain -= seek;
237 if (remain <= 0)
238 break;
239
240 seek = getNextBlock(&dataChunk, dataPtr, mFlags);
241 if (mFlags & FD_ENDIAN_SWAP)
242 swapLen(dataPtr);
243
244 if (seek < 0)
245 break;
246 }
247 }
248
249 void btBulletFile::addDataBlock(char* dataBlock)
250 {
251 m_dataBlocks.push_back(dataBlock);
252 }
253
254 void btBulletFile::writeDNA(FILE* fp)
255 {
256 bChunkInd dataChunk;
257 dataChunk.code = DNA1;
258 dataChunk.dna_nr = 0;
259 dataChunk.nr = 1;
260 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
261 if (VOID_IS_8)
262 {
263 #ifdef _WIN64
264 dataChunk.len = sBulletDNAlen64;
265 dataChunk.oldPtr = sBulletDNAstr64;
266 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
267 fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp);
268 #else
269 btAssert(0);
270 #endif
271 }
272 else
273 {
274 #ifndef _WIN64
275 dataChunk.len = sBulletDNAlen;
276 dataChunk.oldPtr = sBulletDNAstr;
277 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
278 fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp);
279 #else //_WIN64
280 btAssert(0);
281 #endif //_WIN64
282 }
283 #else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
284 if (VOID_IS_8)
285 {
286 dataChunk.len = sBulletDNAlen64;
287 dataChunk.oldPtr = sBulletDNAstr64;
288 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
289 fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp);
290 }
291 else
292 {
293 dataChunk.len = sBulletDNAlen;
294 dataChunk.oldPtr = sBulletDNAstr;
295 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
296 fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp);
297 }
298 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
299 }
300
301 void btBulletFile::parse(int verboseMode)
302 {
303 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
304 if (VOID_IS_8)
305 {
306 #ifdef _WIN64
307
308 if (m_DnaCopy)
309 delete m_DnaCopy;
310 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
311 memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
312 parseInternal(verboseMode, (char*)sBulletDNAstr64, sBulletDNAlen64);
313 #else
314 btAssert(0);
315 #endif
316 }
317 else
318 {
319 #ifndef _WIN64
320
321 if (m_DnaCopy)
322 delete m_DnaCopy;
323 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
324 memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
325 parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen);
326 #else
327 btAssert(0);
328 #endif
329 }
330 #else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
331 if (VOID_IS_8)
332 {
333 if (m_DnaCopy)
334 delete m_DnaCopy;
335 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
336 memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
337 parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen64);
338 }
339 else
340 {
341 if (m_DnaCopy)
342 delete m_DnaCopy;
343 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
344 memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
345 parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen);
346 }
347 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
348
349 //the parsing will convert to cpu endian
350 mFlags &= ~FD_ENDIAN_SWAP;
351
352 int littleEndian = 1;
353 littleEndian = ((char*)&littleEndian)[0];
354
355 mFileBuffer[8] = littleEndian ? 'v' : 'V';
356 }
357
358 // experimental
359 int btBulletFile::write(const char* fileName, bool fixupPointers)
360 {
361 FILE* fp = fopen(fileName, "wb");
362 if (fp)
363 {
364 char header[SIZEOFBLENDERHEADER];
365 memcpy(header, m_headerString, 7);
366 int endian = 1;
367 endian = ((char*)&endian)[0];
368
369 if (endian)
370 {
371 header[7] = '_';
372 }
373 else
374 {
375 header[7] = '-';
376 }
377 if (VOID_IS_8)
378 {
379 header[8] = 'V';
380 }
381 else
382 {
383 header[8] = 'v';
384 }
385
386 header[9] = '2';
387 header[10] = '7';
388 header[11] = '5';
389
390 fwrite(header, SIZEOFBLENDERHEADER, 1, fp);
391
392 writeChunks(fp, fixupPointers);
393
394 writeDNA(fp);
395
396 fclose(fp);
397 }
398 else
399 {
400 printf("Error: cannot open file %s for writing\n", fileName);
401 return 0;
402 }
403 return 1;
404 }
405
406 void btBulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code)
407 {
408 bParse::bChunkInd dataChunk;
409 dataChunk.code = code;
410 dataChunk.nr = 1;
411 dataChunk.len = len;
412 dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
413 dataChunk.oldPtr = oldPtr;
414
416 short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr);
417 int elemBytes;
418 elemBytes = mMemoryDNA->getLength(structInfo[0]);
419 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
420 assert(len == elemBytes);
421
422 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
423 m_chunks.push_back(dataChunk);
424 }
bParse::btBulletFile::m_contactManifolds
btAlignedObjectArray< bStructHandle * > m_contactManifolds
Definition: btBulletFile.h:54
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:264
BT_CONTACTMANIFOLD_CODE
#define BT_CONTACTMANIFOLD_CODE
Definition: btSerializer.h:122
bDNA.h
bParse::btBulletFile::m_dataBlocks
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:56
bParse::bFile::getNextBlock
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1558
bParse::btBulletFile::m_triangleInfoMaps
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:50
BT_CONSTRAINT_CODE
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:113
sBulletDNAlen64
int sBulletDNAlen64
Definition: btSerializer64.cpp:690
bParse::bChunkInd::nr
int nr
Definition: bChunk.h:64
bParse::bFile
Definition: bFile.h:48
bParse::bFile::mMemoryDNA
bDNA * mMemoryDNA
Definition: bFile.h:62
bParse::btBulletFile::m_constraints
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:46
BT_MULTIBODY_CODE
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:108
bParse::bFile::readStruct
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:618
bParse::bFile::parseInternal
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:194
BT_QUANTIZED_BVH_CODE
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:115
bParse::btBulletFile::m_DnaCopy
char * m_DnaCopy
Definition: btBulletFile.h:31
btBulletFile.h
BT_MB_LINKCOLLIDER_CODE
#define BT_MB_LINKCOLLIDER_CODE
Definition: btSerializer.h:109
bParse::bChunkInd::len
int len
Definition: bChunk.h:62
bParse::bChunkInd
Definition: bChunk.h:58
btAssert
#define btAssert(x)
Definition: btScalar.h:133
bParse::btBulletFile::addStruct
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
Definition: btBulletFile.cpp:406
bParse::bFile::mFileBuffer
char * mFileBuffer
Definition: bFile.h:54
bParse::btBulletFile::m_collisionObjects
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:42
BT_SOFTBODY_CODE
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:110
BT_DYNAMICSWORLD_CODE
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:121
bParse::bChunkInd::dna_nr
int dna_nr
Definition: bChunk.h:64
SDNA
#define SDNA
Definition: bDefines.h:105
bParse::btBulletFile::writeDNA
virtual void writeDNA(FILE *fp)
Definition: btBulletFile.cpp:254
bParse::FD_BROKEN_DNA
Definition: bFile.h:36
bParse::bFile::swapLen
void swapLen(char *dataPtr)
Definition: bFile.cpp:333
bParse::bStructHandle
Definition: bCommon.h:32
DNA1
#define DNA1
Definition: bDefines.h:101
sBulletDNAlen
int sBulletDNAlen
Definition: btSerializer.cpp:690
bParse::FD_ENDIAN_SWAP
Definition: bFile.h:31
bParse::btBulletFile::parse
virtual void parse(int verboseMode)
Definition: btBulletFile.cpp:301
bParse::bChunkInd::oldPtr
void * oldPtr
Definition: bChunk.h:63
bParse::VOID_IS_8
const bool VOID_IS_8
Definition: bChunk.h:81
bParse::bChunkInd::code
int code
Definition: bChunk.h:62
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:47
btHashMap::insert
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:264
bParse::bFile::mFlags
int mFlags
Definition: bFile.h:74
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:192
bParse::btBulletFile::m_softBodies
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:38
BT_COLLISIONOBJECT_CODE
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:111
bParse::btBulletFile::m_multiBodyLinkColliders
btAlignedObjectArray< bStructHandle * > m_multiBodyLinkColliders
Definition: btBulletFile.h:36
bParse::bFile::mFileLen
int mFileLen
Definition: bFile.h:55
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:149
sBulletDNAstr
char sBulletDNAstr[]
Definition: btSerializer.cpp:2
SIZEOFBLENDERHEADER
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:23
bParse::btBulletFile::btBulletFile
btBulletFile()
Definition: btBulletFile.cpp:45
bParse::bFile::mDataStart
int mDataStart
Definition: bFile.h:60
bParse::btBulletFile::write
virtual int write(const char *fileName, bool fixupPointers=false)
Definition: btBulletFile.cpp:359
bParse::btBulletFile::addDataBlock
virtual void addDataBlock(char *dataBlock)
Definition: btBulletFile.cpp:249
bParse::btBulletFile::m_bvhs
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:48
bParse::btBulletFile::m_multiBodies
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:34
BT_RIGIDBODY_CODE
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:112
bParse::bFile::m_chunks
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:67
bParse
Definition: btBulletWorldImporter.h:23
bParse::btBulletFile::m_collisionShapes
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:44
bParse::bDNA
Definition: bDNA.h:31
bParse::bDNA::getStruct
short * getStruct(int ind)
Definition: bDNA.cpp:62
bDefines.h
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:46
bParse::bDNA::init
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:345
bParse::bFile::writeChunks
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1498
BT_TRIANLGE_INFO_MAP
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:116
bParse::btBulletFile::m_dynamicsWorldInfo
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:52
bParse::bFile::m_headerString
char m_headerString[7]
Definition: bFile.h:51
BT_SHAPE_CODE
#define BT_SHAPE_CODE
Definition: btSerializer.h:117
bParse::btBulletFile::parseData
virtual void parseData()
Definition: btBulletFile.cpp:104
bParse::btBulletFile::m_rigidBodies
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:40
bParse::bFile::mLibPointers
bPtrMap mLibPointers
Definition: bFile.h:58
bParse::bDNA::getReverseType
int getReverseType(short type)
Definition: bDNA.cpp:76
bParse::bFile::m_chunkPtrPtrMap
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:68
bParse::btBulletFile::~btBulletFile
virtual ~btBulletFile()
Definition: btBulletFile.cpp:90
bParse::bDNA::getLength
short getLength(int ind)
Definition: bDNA.cpp:69
bParse::ChunkUtils::getOffset
static int getOffset(int flags)
Definition: bChunk.cpp:49
sBulletDNAstr64
char sBulletDNAstr64[]
Definition: btSerializer64.cpp:2