3 Copyright (c) 2006-2010 Erwin Coumans http://gamekit.googlecode.com
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:
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.
16 #include "b3BulletFile.h"
17 #include "b3Defines.h"
20 #if !defined(__CELLOS_LV2__) && !defined(__MWERKS__)
25 // 32 && 64 bit versions
26 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
28 extern char b3s_bulletDNAstr64[];
29 extern int b3s_bulletDNAlen64;
31 extern char b3s_bulletDNAstr[];
32 extern int b3s_bulletDNAlen;
34 #else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
36 extern char b3s_bulletDNAstr64[];
37 extern int b3s_bulletDNAlen64;
38 extern char b3s_bulletDNAstr[];
39 extern int b3s_bulletDNAlen;
41 #endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
43 using namespace bParse;
45 b3BulletFile::b3BulletFile()
46 : bFile("", "BULLET ")
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"
52 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
54 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
55 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
56 mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen64);
58 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
59 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
60 mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen);
62 #else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
65 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
66 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
67 mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen64);
71 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
72 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
73 mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen);
75 #endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
78 b3BulletFile::b3BulletFile(const char* fileName)
79 : bFile(fileName, "BULLET ")
84 b3BulletFile::b3BulletFile(char* memoryBuffer, int len)
85 : bFile(memoryBuffer, len, "BULLET ")
90 b3BulletFile::~b3BulletFile()
93 b3AlignedFree(m_DnaCopy);
95 while (m_dataBlocks.size())
97 char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1];
99 m_dataBlocks.pop_back();
103 // ----------------------------------------------------- //
104 void b3BulletFile::parseData()
106 // printf ("Building datablocks");
107 // printf ("Chunk size = %d",CHUNK_HEADER_LEN);
108 // printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
110 const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0;
112 //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
116 char* dataPtr = mFileBuffer + mDataStart;
121 //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
122 int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
124 if (mFlags & FD_ENDIAN_SWAP)
127 //dataPtr += ChunkUtils::getOffset(mFlags);
128 char* dataPtrHead = 0;
130 while (dataChunk.code != B3_DNA1)
132 if (!brokenDNA || (dataChunk.code != B3_QUANTIZED_BVH_CODE))
135 if (dataChunk.code == B3_SDNA) break;
136 //if (dataChunk.code == DNA1) break;
138 // same as (BHEAD+DATA dependency)
139 dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags);
140 if (dataChunk.dna_nr >= 0)
142 char* id = readStruct(dataPtrHead, dataChunk);
147 m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
148 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
150 m_chunks.push_back(dataChunk);
152 //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
154 // listID->push_back((bStructHandle*)id);
157 if (dataChunk.code == B3_SOFTBODY_CODE)
159 m_softBodies.push_back((bStructHandle*)id);
162 if (dataChunk.code == B3_RIGIDBODY_CODE)
164 m_rigidBodies.push_back((bStructHandle*)id);
167 if (dataChunk.code == B3_DYNAMICSWORLD_CODE)
169 m_dynamicsWorldInfo.push_back((bStructHandle*)id);
172 if (dataChunk.code == B3_CONSTRAINT_CODE)
174 m_constraints.push_back((bStructHandle*)id);
177 if (dataChunk.code == B3_QUANTIZED_BVH_CODE)
179 m_bvhs.push_back((bStructHandle*)id);
182 if (dataChunk.code == B3_TRIANLGE_INFO_MAP)
184 m_triangleInfoMaps.push_back((bStructHandle*)id);
187 if (dataChunk.code == B3_COLLISIONOBJECT_CODE)
189 m_collisionObjects.push_back((bStructHandle*)id);
192 if (dataChunk.code == B3_SHAPE_CODE)
194 m_collisionShapes.push_back((bStructHandle*)id);
197 // if (dataChunk.code == GLOB)
199 // m_glob = (bStructHandle*) id;
204 //printf("unknown chunk\n");
206 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
211 printf("skipping B3_QUANTIZED_BVH_CODE due to broken DNA\n");
216 seek = getNextBlock(&dataChunk, dataPtr, mFlags);
217 if (mFlags & FD_ENDIAN_SWAP)
225 void b3BulletFile::addDataBlock(char* dataBlock)
227 m_dataBlocks.push_back(dataBlock);
230 void b3BulletFile::writeDNA(FILE* fp)
233 dataChunk.code = B3_DNA1;
234 dataChunk.dna_nr = 0;
236 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
240 dataChunk.len = b3s_bulletDNAlen64;
241 dataChunk.oldPtr = b3s_bulletDNAstr64;
242 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
243 fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64, 1, fp);
251 dataChunk.len = b3s_bulletDNAlen;
252 dataChunk.oldPtr = b3s_bulletDNAstr;
253 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
254 fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen, 1, fp);
259 #else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
262 dataChunk.len = b3s_bulletDNAlen64;
263 dataChunk.oldPtr = b3s_bulletDNAstr64;
264 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
265 fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64, 1, fp);
269 dataChunk.len = b3s_bulletDNAlen;
270 dataChunk.oldPtr = b3s_bulletDNAstr;
271 fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
272 fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen, 1, fp);
274 #endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
277 void b3BulletFile::parse(int verboseMode)
279 #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
286 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
287 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
288 parseInternal(verboseMode, (char*)b3s_bulletDNAstr64, b3s_bulletDNAlen64);
299 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
300 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
301 parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen);
306 #else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
311 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16);
312 memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64);
313 parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen64);
319 m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16);
320 memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen);
321 parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen);
323 #endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
325 //the parsing will convert to cpu endian
326 mFlags &= ~FD_ENDIAN_SWAP;
328 int littleEndian = 1;
329 littleEndian = ((char*)&littleEndian)[0];
331 mFileBuffer[8] = littleEndian ? 'v' : 'V';
335 int b3BulletFile::write(const char* fileName, bool fixupPointers)
337 FILE* fp = fopen(fileName, "wb");
340 char header[B3_SIZEOFBLENDERHEADER];
341 memcpy(header, m_headerString, 7);
343 endian = ((char*)&endian)[0];
366 fwrite(header, B3_SIZEOFBLENDERHEADER, 1, fp);
368 writeChunks(fp, fixupPointers);
376 printf("Error: cannot open file %s for writing\n", fileName);
382 void b3BulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code)
384 bParse::bChunkInd dataChunk;
385 dataChunk.code = code;
388 dataChunk.dna_nr = mMemoryDNA->getReverseType(structType);
389 dataChunk.oldPtr = oldPtr;
391 ///Perform structure size validation
392 short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr);
394 elemBytes = mMemoryDNA->getLength(structInfo[0]);
395 // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
396 assert(len == elemBytes);
398 mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
399 m_chunks.push_back(dataChunk);