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
57#else //_WIN64
61#endif //_WIN64
62#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
63 if (VOID_IS_8)
64 {
68 }
69 else
70 {
74 }
75#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
76}
77
78btBulletFile::btBulletFile(const char* fileName)
79 : bFile(fileName, "BULLET ")
80{
81 m_DnaCopy = 0;
82}
83
84btBulletFile::btBulletFile(char* memoryBuffer, int len)
85 : bFile(memoryBuffer, len, "BULLET ")
86{
87 m_DnaCopy = 0;
88}
89
91{
92 if (m_DnaCopy)
94
95 while (m_dataBlocks.size())
96 {
97 char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1];
98 delete[] dataBlock;
100 }
101}
102
103// ----------------------------------------------------- //
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
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 {
167 }
168 if (dataChunk.code == BT_MULTIBODY_CODE)
169 {
171 }
172
173 if (dataChunk.code == BT_MB_LINKCOLLIDER_CODE)
174 {
176 }
177
178 if (dataChunk.code == BT_SOFTBODY_CODE)
179 {
181 }
182
183 if (dataChunk.code == BT_RIGIDBODY_CODE)
184 {
186 }
187
188 if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
189 {
191 }
192
193 if (dataChunk.code == BT_CONSTRAINT_CODE)
194 {
196 }
197
198 if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
199 {
201 }
202
203 if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
204 {
206 }
207
208 if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
209 {
211 }
212
213 if (dataChunk.code == BT_SHAPE_CODE)
214 {
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);
242 swapLen(dataPtr);
243
244 if (seek < 0)
245 break;
246 }
247}
248
249void btBulletFile::addDataBlock(char* dataBlock)
250{
251 m_dataBlocks.push_back(dataBlock);
252}
253
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
301void 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;
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;
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;
336 memset(m_DnaCopy, 0, sBulletDNAlen64);
339 }
340 else
341 {
342 if (m_DnaCopy)
343 delete m_DnaCopy;
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
360int 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
407void 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}
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:23
#define DNA1
Definition: bDefines.h:101
#define SDNA
Definition: bDefines.h:105
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
int sBulletDNAlen64
char sBulletDNAstr[]
Definition: btSerializer.cpp:1
char sBulletDNAstr64[]
int sBulletDNAlen
#define btAssert(x)
Definition: btScalar.h:153
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:111
#define BT_CONTACTMANIFOLD_CODE
Definition: btSerializer.h:122
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:116
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:115
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:112
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:121
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:110
#define BT_SHAPE_CODE
Definition: btSerializer.h:117
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:113
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:108
#define BT_MB_LINKCOLLIDER_CODE
Definition: btSerializer.h:109
static int getOffset(int flags)
Definition: bChunk.cpp:49
void * oldPtr
Definition: bChunk.h:63
short getLength(int ind)
Definition: bDNA.cpp:69
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:345
int getReverseType(short type)
Definition: bDNA.cpp:76
short * getStruct(int ind)
Definition: bDNA.cpp:62
int mFileLen
Definition: bFile.h:55
bDNA * mMemoryDNA
Definition: bFile.h:62
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:195
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:67
int mDataStart
Definition: bFile.h:60
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:68
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:619
bPtrMap mLibPointers
Definition: bFile.h:58
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1499
char * mFileBuffer
Definition: bFile.h:54
void swapLen(char *dataPtr)
Definition: bFile.cpp:334
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1559
char m_headerString[7]
Definition: bFile.h:51
int mFlags
Definition: bFile.h:74
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:52
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:40
virtual void parse(int verboseMode)
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:50
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:48
virtual void addDataBlock(char *dataBlock)
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:34
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:46
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:56
virtual int write(const char *fileName, bool fixupPointers=false)
btAlignedObjectArray< bStructHandle * > m_contactManifolds
Definition: btBulletFile.h:54
virtual void parseData()
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:42
btAlignedObjectArray< bStructHandle * > m_multiBodyLinkColliders
Definition: btBulletFile.h:36
virtual void writeDNA(FILE *fp)
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:38
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:44
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
int size() const
return the number of elements in the array
void push_back(const T &_Val)
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:264
const bool VOID_IS_8
Definition: bChunk.h:81
@ FD_ENDIAN_SWAP
Definition: bFile.h:31
@ FD_BROKEN_DNA
Definition: bFile.h:36