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
26// 32 && 64 bit versions
27#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
28#ifdef _WIN64
29extern char sBulletDNAstr64[];
30extern int sBulletDNAlen64;
31#else
32extern char sBulletDNAstr[];
33extern int sBulletDNAlen;
34#endif //_WIN64
35#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
36
37extern char sBulletDNAstr64[];
38extern int sBulletDNAlen64;
39extern char sBulletDNAstr[];
40extern int sBulletDNAlen;
41
42#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
43
44using namespace bParse;
45
46btBulletFile::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
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
82btBulletFile::btBulletFile(const char* fileName)
83:bFile(fileName, "BULLET ")
84{
85 m_DnaCopy = 0;
86}
87
88
89
90btBulletFile::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;
107 m_dataBlocks.pop_back();
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 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
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);
247 swapLen(dataPtr);
248
249 if (seek < 0)
250 break;
251 }
252
253}
254
255void btBulletFile::addDataBlock(char* dataBlock)
256{
257 m_dataBlocks.push_back(dataBlock);
258
259}
260
261
262
263
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
313void 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;
325#else
326 btAssert(0);
327#endif
328 }
329 else
330 {
331#ifndef _WIN64
332
333 if (m_DnaCopy)
334 delete m_DnaCopy;
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;
350 }
351 else
352 {
353 if (m_DnaCopy)
354 delete m_DnaCopy;
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
372int 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
419void 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
#define SIZEOFBLENDERHEADER
Definition: bDefines.h:24
#define DNA1
Definition: bDefines.h:107
#define SDNA
Definition: bDefines.h:111
#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:131
#define BT_COLLISIONOBJECT_CODE
Definition: btSerializer.h:119
#define BT_TRIANLGE_INFO_MAP
Definition: btSerializer.h:124
#define BT_QUANTIZED_BVH_CODE
Definition: btSerializer.h:123
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:120
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:129
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:118
#define BT_SHAPE_CODE
Definition: btSerializer.h:125
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:121
#define BT_MULTIBODY_CODE
Definition: btSerializer.h:117
static int getOffset(int flags)
Definition: bChunk.cpp:51
void * oldPtr
Definition: bChunk.h:67
short getLength(int ind)
Definition: bDNA.cpp:74
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:349
int getReverseType(short type)
Definition: bDNA.cpp:82
short * getStruct(int ind)
Definition: bDNA.cpp:66
int mFileLen
Definition: bFile.h:56
bDNA * mMemoryDNA
Definition: bFile.h:64
virtual void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:203
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:69
int mDataStart
Definition: bFile.h:62
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:70
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:657
bPtrMap mLibPointers
Definition: bFile.h:60
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1577
char * mFileBuffer
Definition: bFile.h:55
void swapLen(char *dataPtr)
Definition: bFile.cpp:356
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1641
char m_headerString[7]
Definition: bFile.h:52
int mFlags
Definition: bFile.h:77
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:58
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:46
virtual void parse(int verboseMode)
btAlignedObjectArray< bStructHandle * > m_triangleInfoMaps
Definition: btBulletFile.h:56
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:54
virtual void addDataBlock(char *dataBlock)
btAlignedObjectArray< bStructHandle * > m_multiBodies
Definition: btBulletFile.h:42
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:52
btAlignedObjectArray< char * > m_dataBlocks
Definition: btBulletFile.h:60
virtual int write(const char *fileName, bool fixupPointers=false)
virtual void parseData()
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:48
virtual void writeDNA(FILE *fp)
btAlignedObjectArray< bStructHandle * > m_softBodies
Definition: btBulletFile.h:44
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:50
void addStruct(const char *structType, void *data, int len, void *oldPtr, int code)
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:274
Definition: bChunk.h:29
const bool VOID_IS_8
Definition: bChunk.h:89
@ FD_ENDIAN_SWAP
Definition: bFile.h:31
@ FD_BROKEN_DNA
Definition: bFile.h:36