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

Bullet Collision Detection & Physics Library

btBulletFile.cpp
Go to the documentation of this file.
1/*
2bParse
3Copyright (c) 2006-2010 Erwin Coumans http://gamekit.googlecode.com
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. 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
28extern char sBulletDNAstr64[];
29extern int sBulletDNAlen64;
30#else
31extern char sBulletDNAstr[];
32extern int sBulletDNAlen;
33#endif //_WIN64
34#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
35
36extern char sBulletDNAstr64[];
37extern int sBulletDNAlen64;
38extern char sBulletDNAstr[];
39extern int sBulletDNAlen;
40
41#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
42
43using namespace bParse;
44
45btBulletFile::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
90btBulletFile::~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 memset(m_DnaCopy, 0, sBulletDNAlen64);
337 memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
338 parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen64);
339 }
340 else
341 {
342 if (m_DnaCopy)
343 delete m_DnaCopy;
344 m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
345 memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
346 parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen);
347 }
348#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
349
350 //the parsing will convert to cpu endian
351 mFlags &= ~FD_ENDIAN_SWAP;
352
353 int littleEndian = 1;
354 littleEndian = ((char*)&littleEndian)[0];
355
356 mFileBuffer[8] = littleEndian ? 'v' : 'V';
357}
358
359// experimental
360 int btBulletFile::write(const char* fileName, bool fixupPointers)
361{
362 FILE* fp = fopen(fileName, "wb");
363 if (fp)
364 {
365 char header[SIZEOFBLENDERHEADER];
366 memcpy(header, m_headerString, 7);
367 int endian = 1;
368 endian = ((char*)&endian)[0];
369
370 if (endian)
371 {
372 header[7] = '_';
373 }
374 else
375 {
376 header[7] = '-';
377 }
378 if (VOID_IS_8)
379 {
380 header[8] = 'V';
381 }
382 else
383 {
384 header[8] = 'v';
385 }
386
387 header[9] = '2';
388 header[10] = '7';
389 header[11] = '5';
390
391 fwrite(header, SIZEOFBLENDERHEADER, 1, fp);
392
393 writeChunks(fp, fixupPointers);
394
395 writeDNA(fp);
396
397 fclose(fp);
398 }
399 else
400 {
401 printf("Error: cannot open file %s for writing\n", fileName);
402 return 0;
403 }
404 return 1;
405}
406
407 void btBulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code)
408{
409 bParse::bChunkInd dataChunk;
410 dataChunk.code = code;
411 dataChunk.nr = 1;
412 dataChunk.len = len;
413 dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
414 dataChunk.oldPtr = oldPtr;
415
417 short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr);
418 int elemBytes;
419 elemBytes = mMemoryDNA->getLength(structInfo[0]);
420 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
421 assert(len == elemBytes);
422
423 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
424 m_chunks.push_back(dataChunk);
425}
bDNA.h
bDefines.h
SIZEOFBLENDERHEADER
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:23
DNA1
#define DNA1
Definition: bDefines.h:101
SDNA
#define SDNA
Definition: bDefines.h:105
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:47
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:46
sBulletDNAlen64
int sBulletDNAlen64
Definition: btSerializer64.cpp:692
sBulletDNAstr
char sBulletDNAstr[]
Definition: btSerializer.cpp:1
sBulletDNAstr64
char sBulletDNAstr64[]
Definition: btSerializer64.cpp:1
sBulletDNAlen
int sBulletDNAlen
Definition: btSerializer.cpp:692
btBulletFile.h
btAssert
#define btAssert(x)
Definition: btScalar.h:153
BT_COLLISIONOBJECT_CODE
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:111
BT_CONTACTMANIFOLD_CODE
#define BT_CONTACTMANIFOLD_CODE
Definition: btSerializer.h:122
BT_TRIANLGE_INFO_MAP
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:116
BT_QUANTIZED_BVH_CODE
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:115
BT_RIGIDBODY_CODE
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:112
BT_DYNAMICSWORLD_CODE
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:121
BT_SOFTBODY_CODE
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:110
BT_SHAPE_CODE
#define BT_SHAPE_CODE
Definition: btSerializer.h:117
BT_CONSTRAINT_CODE
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:113
BT_MULTIBODY_CODE
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:108
BT_MB_LINKCOLLIDER_CODE
#define BT_MB_LINKCOLLIDER_CODE
Definition: btSerializer.h:109
bParse::ChunkUtils::getOffset
static int getOffset(int flags)
Definition: bChunk.cpp:49
bParse::bChunkInd
Definition: bChunk.h:59
bParse::bChunkInd::code
int code
Definition: bChunk.h:62
bParse::bChunkInd::len
int len
Definition: bChunk.h:62
bParse::bChunkInd::dna_nr
int dna_nr
Definition: bChunk.h:64
bParse::bChunkInd::oldPtr
void * oldPtr
Definition: bChunk.h:63
bParse::bChunkInd::nr
int nr
Definition: bChunk.h:64
bParse::bDNA
Definition: bDNA.h:32
bParse::bDNA::getLength
short getLength(int ind)
Definition: bDNA.cpp:69
bParse::bDNA::init
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:345
bParse::bDNA::getReverseType
int getReverseType(short type)
Definition: bDNA.cpp:76
bParse::bDNA::getStruct
short * getStruct(int ind)
Definition: bDNA.cpp:62
bParse::bFile
Definition: bFile.h:49
bParse::bFile::mFileLen
int mFileLen
Definition: bFile.h:55
bParse::bFile::mMemoryDNA
bDNA * mMemoryDNA
Definition: bFile.h:62
bParse::bFile::parseInternal
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:195
bParse::bFile::m_chunks
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:67
bParse::bFile::mDataStart
int mDataStart
Definition: bFile.h:60
bParse::bFile::m_chunkPtrPtrMap
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:68
bParse::bFile::readStruct
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:619
bParse::bFile::mLibPointers
bPtrMap mLibPointers
Definition: bFile.h:58
bParse::bFile::writeChunks
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1499
bParse::bFile::mFileBuffer
char * mFileBuffer
Definition: bFile.h:54
bParse::bFile::swapLen
void swapLen(char *dataPtr)
Definition: bFile.cpp:334
bParse::bFile::getNextBlock
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1559
bParse::bFile::m_headerString
char m_headerString[7]
Definition: bFile.h:51
bParse::bFile::mFlags
int mFlags
Definition: bFile.h:74
bParse::btBulletFile::m_dynamicsWorldInfo
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:52
bParse::btBulletFile::m_rigidBodies
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:40
bParse::btBulletFile::parse
virtual void parse(int verboseMode)
Definition: btBulletFile.cpp:301
bParse::btBulletFile::m_triangleInfoMaps
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:50
bParse::btBulletFile::m_bvhs
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:48
bParse::btBulletFile::addDataBlock
virtual void addDataBlock(char *dataBlock)
Definition: btBulletFile.cpp:249
bParse::btBulletFile::m_multiBodies
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:34
bParse::btBulletFile::m_constraints
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:46
bParse::btBulletFile::~btBulletFile
virtual ~btBulletFile()
Definition: btBulletFile.cpp:90
bParse::btBulletFile::m_dataBlocks
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:56
bParse::btBulletFile::write
virtual int write(const char *fileName, bool fixupPointers=false)
Definition: btBulletFile.cpp:360
bParse::btBulletFile::m_contactManifolds
btAlignedObjectArray< bStructHandle * > m_contactManifolds
Definition: btBulletFile.h:54
bParse::btBulletFile::btBulletFile
btBulletFile()
Definition: btBulletFile.cpp:45
bParse::btBulletFile::parseData
virtual void parseData()
Definition: btBulletFile.cpp:104
bParse::btBulletFile::m_collisionObjects
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:42
bParse::btBulletFile::m_multiBodyLinkColliders
btAlignedObjectArray< bStructHandle * > m_multiBodyLinkColliders
Definition: btBulletFile.h:36
bParse::btBulletFile::m_DnaCopy
char * m_DnaCopy
Definition: btBulletFile.h:31
bParse::btBulletFile::writeDNA
virtual void writeDNA(FILE *fp)
Definition: btBulletFile.cpp:254
bParse::btBulletFile::m_softBodies
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:38
bParse::btBulletFile::m_collisionShapes
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:44
bParse::btBulletFile::addStruct
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
Definition: btBulletFile.cpp:407
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:142
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:257
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:185
btHashMap::insert
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:264
bParse
Definition: btBulletWorldImporter.h:24
bParse::VOID_IS_8
const bool VOID_IS_8
Definition: bChunk.h:81
bParse::FD_ENDIAN_SWAP
@ FD_ENDIAN_SWAP
Definition: bFile.h:31
bParse::FD_BROKEN_DNA
@ FD_BROKEN_DNA
Definition: bFile.h:36
bParse::bStructHandle
Definition: bCommon.h:33