Home | History | Annotate | Download | only in BulletFileLoader
      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 
     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 
     82 btBulletFile::btBulletFile(const char* fileName)
     83 :bFile(fileName, "BULLET ")
     84 {
     85 	m_DnaCopy = 0;
     86 }
     87 
     88 
     89 
     90 btBulletFile::btBulletFile(char *memoryBuffer, int len)
     91 :bFile(memoryBuffer,len, "BULLET ")
     92 {
     93 	m_DnaCopy = 0;
     94 }
     95 
     96 
     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 // ----------------------------------------------------- //
    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 
    252 void	btBulletFile::addDataBlock(char* dataBlock)
    253 {
    254 	m_dataBlocks.push_back(dataBlock);
    255 
    256 }
    257 
    258 
    259 
    260 
    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 
    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
    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 
    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