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