diff options
Diffstat (limited to 'thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp')
-rw-r--r-- | thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp | 1739 |
1 files changed, 0 insertions, 1739 deletions
diff --git a/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp b/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp deleted file mode 100644 index 432f7fc2b4..0000000000 --- a/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp +++ /dev/null @@ -1,1739 +0,0 @@ -/* -bParse -Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -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. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ -#include "b3File.h" -#include "b3Common.h" -#include "b3Chunk.h" -#include "b3DNA.h" -#include <math.h> -#include <string.h> -#include <stdlib.h> -#include "b3Defines.h" -#include "Bullet3Serialize/Bullet2FileLoader/b3Serializer.h" -#include "Bullet3Common/b3AlignedAllocator.h" -#include "Bullet3Common/b3MinMax.h" - -#define B3_SIZEOFBLENDERHEADER 12 -#define MAX_ARRAY_LENGTH 512 -using namespace bParse; -#define MAX_STRLEN 1024 - -const char* getCleanName(const char* memName, char* buffer) -{ - int slen = strlen(memName); - assert(slen<MAX_STRLEN); - slen=b3Min(slen,MAX_STRLEN); - for (int i=0;i<slen;i++) - { - if (memName[i]==']'||memName[i]=='[') - { - buffer[i] = 0;//'_'; - } else - { - buffer[i] = memName[i]; - } - } - buffer[slen]=0; - return buffer; -} - - - -// ----------------------------------------------------- // -bFile::bFile(const char *filename, const char headerString[7]) - : mOwnsBuffer(true), - mFileBuffer(0), - mFileLen(0), - mVersion(0), - mDataStart(0), - mFileDNA(0), - mMemoryDNA(0), - mFlags(FD_INVALID) -{ - for (int i=0;i<7;i++) - { - m_headerString[i] = headerString[i]; - } - - FILE *fp = fopen(filename, "rb"); - if (fp) - { - fseek(fp, 0L, SEEK_END); - mFileLen = ftell(fp); - fseek(fp, 0L, SEEK_SET); - - mFileBuffer = (char*)malloc(mFileLen+1); - int bytesRead; - bytesRead = fread(mFileBuffer, mFileLen, 1, fp); - - fclose(fp); - - // - parseHeader(); - - } -} - -// ----------------------------------------------------- // -bFile::bFile( char *memoryBuffer, int len, const char headerString[7]) -: mOwnsBuffer(false), - mFileBuffer(0), - mFileLen(0), - mVersion(0), - mDataStart(0), - mFileDNA(0), - mMemoryDNA(0), - mFlags(FD_INVALID) -{ - for (int i=0;i<7;i++) - { - m_headerString[i] = headerString[i]; - } - mFileBuffer = memoryBuffer; - mFileLen = len; - - parseHeader(); - -} - - -// ----------------------------------------------------- // -bFile::~bFile() -{ - if (mOwnsBuffer && mFileBuffer) - { - free(mFileBuffer); - mFileBuffer = 0; - } - - - delete mMemoryDNA; - delete mFileDNA; -} - - - - - -// ----------------------------------------------------- // -void bFile::parseHeader() -{ - if (!mFileLen || !mFileBuffer) - return; - - char *blenderBuf = mFileBuffer; - char header[B3_SIZEOFBLENDERHEADER+1] ; - memcpy(header, blenderBuf, B3_SIZEOFBLENDERHEADER); - header[B3_SIZEOFBLENDERHEADER]='\0'; - - if (strncmp(header, m_headerString, 6)!=0) - { - memcpy(header, m_headerString, B3_SIZEOFBLENDERHEADER); - return; - } - - if (header[6] == 'd') - { - mFlags |= FD_DOUBLE_PRECISION; - } - - char *ver = header+9; - mVersion = atoi(ver); - if (mVersion <= 241) - { - //printf("Warning, %d not fully tested : <= 242\n", mVersion); - } - - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - // swap ptr sizes... - if (header[7]=='-') - { - mFlags |= FD_FILE_64; - if (!VOID_IS_8) - mFlags |= FD_BITS_VARIES; - } - else if (VOID_IS_8) mFlags |= FD_BITS_VARIES; - - // swap endian... - if (header[8]=='V') - { - if (littleEndian ==1) - mFlags |= FD_ENDIAN_SWAP; - } - else - if (littleEndian==0) - mFlags |= FD_ENDIAN_SWAP; - - - mFlags |= FD_OK; -} - -// ----------------------------------------------------- // -bool bFile::ok() -{ - return (mFlags &FD_OK)!=0; -} - -// ----------------------------------------------------- // -void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) -{ - if ( (mFlags &FD_OK) ==0) - return; - - char *blenderData = mFileBuffer; - bChunkInd dna; - dna.oldPtr = 0; - - char *tempBuffer = blenderData; - for (int i=0; i<mFileLen; i++) - { - // looking for the data's starting position - // and the start of SDNA decls - - if (!mDataStart && strncmp(tempBuffer, "REND", 4)==0) - mDataStart = i; - - if (strncmp(tempBuffer, "DNA1", 4)==0) - { - // read the DNA1 block and extract SDNA - if (getNextBlock(&dna, tempBuffer, mFlags) > 0) - { - if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0) - dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags)); - else dna.oldPtr = 0; - } - else dna.oldPtr = 0; - } - // Some Bullet files are missing the DNA1 block - // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME - // In Bullet tests its SDNA + NAME - else if (strncmp(tempBuffer, "SDNANAME", 8) ==0) - { - dna.oldPtr = blenderData + i; - dna.len = mFileLen-i; - - // Also no REND block, so exit now. - if (mVersion==276) break; - } - - if (mDataStart && dna.oldPtr) break; - tempBuffer++; - } - if (!dna.oldPtr || !dna.len) - { - //printf("Failed to find DNA1+SDNA pair\n"); - mFlags &= ~FD_OK; - return; - } - - - mFileDNA = new bDNA(); - - - ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary - mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0); - - - if (mVersion==276) - { - int i; - for (i=0;i<mFileDNA->getNumNames();i++) - { - if (strcmp(mFileDNA->getName(i),"int")==0) - { - mFlags |= FD_BROKEN_DNA; - } - } - if ((mFlags&FD_BROKEN_DNA)!=0) - { - //printf("warning: fixing some broken DNA version\n"); - } - } - - - - if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) - mFileDNA->dumpTypeDefinitions(); - - mMemoryDNA = new bDNA(); - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - mMemoryDNA->init(memDna,memDnaLength,littleEndian==0); - - - - - ///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files - if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames()) - { - mFlags |= FD_VERSION_VARIES; - //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform"); - } - - // as long as it kept up to date it will be ok!! - if (mMemoryDNA->lessThan(mFileDNA)) - { - //printf ("Warning, file DNA is newer than built in."); - } - - - mFileDNA->initCmpFlags(mMemoryDNA); - - parseData(); - - resolvePointers(verboseMode); - - updateOldPointers(); - - -} - - - -// ----------------------------------------------------- // -void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag) -{ - char *data = head; - short *strc = mFileDNA->getStruct(dataChunk.dna_nr); - - - - const char s[] = "SoftBodyMaterialData"; - int szs = sizeof(s); - if (strncmp((char*)&dataChunk.code,"ARAY",4)==0) - { - short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); - char *oldType = mFileDNA->getType(oldStruct[0]); - if (strncmp(oldType,s,szs)==0) - { - return; - } - } - - - int len = mFileDNA->getLength(strc[0]); - - for (int i=0; i<dataChunk.nr; i++) - { - swapStruct(dataChunk.dna_nr, data,ignoreEndianFlag); - data+=len; - } -} - -void bFile::swapLen(char *dataPtr) -{ - const bool VOID_IS_8 = ((sizeof(void*)==8)); - if (VOID_IS_8) - { - if (mFlags &FD_BITS_VARIES) - { - bChunkPtr4*c = (bChunkPtr4*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - B3_SWITCH_INT(c->len); - B3_SWITCH_INT(c->dna_nr); - B3_SWITCH_INT(c->nr); - } else - { - bChunkPtr8* c = (bChunkPtr8*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - B3_SWITCH_INT(c->len); - B3_SWITCH_INT(c->dna_nr); - B3_SWITCH_INT(c->nr); - - } - } else - { - if (mFlags &FD_BITS_VARIES) - { - bChunkPtr8*c = (bChunkPtr8*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - B3_SWITCH_INT(c->len); - B3_SWITCH_INT(c->dna_nr); - B3_SWITCH_INT(c->nr); - - } else - { - bChunkPtr4* c = (bChunkPtr4*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - B3_SWITCH_INT(c->len); - - B3_SWITCH_INT(c->dna_nr); - B3_SWITCH_INT(c->nr); - - } - } - -} - - -void bFile::swapDNA(char* ptr) -{ - bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0); - - char* data = &ptr[20]; -// void bDNA::init(char *data, int len, bool swap) - int *intPtr=0;short *shtPtr=0; - char *cp = 0;int dataLen =0; - //long nr=0; - intPtr = (int*)data; - - /* - SDNA (4 bytes) (magic number) - NAME (4 bytes) - <nr> (4 bytes) amount of names (int) - <string> - <string> - */ - - if (strncmp(data, "SDNA", 4)==0) - { - // skip ++ NAME - intPtr++; intPtr++; - } - - - - // Parse names - if (swap) - dataLen = ChunkUtils::swapInt(*intPtr); - else - dataLen = *intPtr; - - *intPtr = ChunkUtils::swapInt(*intPtr); - intPtr++; - - cp = (char*)intPtr; - int i; - for ( i=0; i<dataLen; i++) - { - while (*cp)cp++; - cp++; - } - - - cp = b3AlignPointer(cp,4); - - /* - TYPE (4 bytes) - <nr> amount of types (int) - <string> - <string> - */ - - intPtr = (int*)cp; - assert(strncmp(cp, "TYPE", 4)==0); intPtr++; - - if (swap) - dataLen = ChunkUtils::swapInt(*intPtr); - else - dataLen = *intPtr; - - *intPtr = ChunkUtils::swapInt(*intPtr); - - intPtr++; - - cp = (char*)intPtr; - for ( i=0; i<dataLen; i++) - { - while (*cp)cp++; - cp++; - } - - cp = b3AlignPointer(cp,4); - - /* - TLEN (4 bytes) - <len> (short) the lengths of types - <len> - */ - - // Parse type lens - intPtr = (int*)cp; - assert(strncmp(cp, "TLEN", 4)==0); intPtr++; - - - shtPtr = (short*)intPtr; - for ( i=0; i<dataLen; i++, shtPtr++) - { - //??????if (swap) - shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); - } - - if (dataLen & 1) - shtPtr++; - - /* - STRC (4 bytes) - <nr> amount of structs (int) - <typenr> - <nr_of_elems> - <typenr> - <namenr> - <typenr> - <namenr> - */ - - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - assert(strncmp(cp, "STRC", 4)==0); - intPtr++; - - if (swap) - dataLen = ChunkUtils::swapInt(*intPtr); - else - dataLen = *intPtr; - - *intPtr = ChunkUtils::swapInt(*intPtr); - - intPtr++; - - - shtPtr = (short*)intPtr; - for ( i=0; i<dataLen; i++) - { - - //if (swap) - { - int len = shtPtr[1]; - - shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]); - shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]); - - shtPtr+= 2; - - for (int a=0; a<len; a++, shtPtr+=2) - { - shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]); - shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]); - } - } -// else -// shtPtr+= (2*shtPtr[1])+2; - } - -} - -void bFile::writeFile(const char* fileName) -{ - FILE* f = fopen(fileName,"wb"); - fwrite(mFileBuffer,1,mFileLen,f); - fclose(f); -} - -void bFile::preSwap() -{ - - //const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0; - //FD_ENDIAN_SWAP - //byte 8 determines the endianness of the file, little (v) versus big (V) - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - - if (mFileBuffer[8]=='V') - { - mFileBuffer[8]='v'; - } - else - { - mFileBuffer[8]='V'; - } - - - - - - - mDataStart = 12; - - char *dataPtr = mFileBuffer+mDataStart; - - bChunkInd dataChunk; - dataChunk.code = 0; - bool ignoreEndianFlag = true; - - //we always want to swap here - - int seek = getNextBlock(&dataChunk, dataPtr, mFlags); - //dataPtr += ChunkUtils::getOffset(mFlags); - char *dataPtrHead = 0; - - while (1) - { - // one behind - if (dataChunk.code == B3_SDNA || dataChunk.code==B3_DNA1 || dataChunk.code == B3_TYPE || dataChunk.code == B3_TLEN || dataChunk.code==B3_STRC) - { - - swapDNA(dataPtr); - break; - } else - { - //if (dataChunk.code == DNA1) break; - dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); - - swapLen(dataPtr); - if (dataChunk.dna_nr>=0) - { - swap(dataPtrHead, dataChunk,ignoreEndianFlag); - } else - { - //printf("unknown chunk\n"); - } - } - - // next please! - dataPtr += seek; - - seek = getNextBlock(&dataChunk, dataPtr, mFlags); - if (seek < 0) - break; - } - - if (mFlags & FD_ENDIAN_SWAP) - { - mFlags &= ~FD_ENDIAN_SWAP; - } else - { - mFlags |= FD_ENDIAN_SWAP; - } - - - -} - - -// ----------------------------------------------------- // -char* bFile::readStruct(char *head, bChunkInd& dataChunk) -{ - bool ignoreEndianFlag = false; - - if (mFlags & FD_ENDIAN_SWAP) - swap(head, dataChunk, ignoreEndianFlag); - - - - if (!mFileDNA->flagEqual(dataChunk.dna_nr)) - { - // Ouch! need to rebuild the struct - short *oldStruct,*curStruct; - char *oldType, *newType; - int oldLen, curLen, reverseOld; - - - oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); - oldType = mFileDNA->getType(oldStruct[0]); - - oldLen = mFileDNA->getLength(oldStruct[0]); - - if ((mFlags&FD_BROKEN_DNA)!=0) - { - if ((strcmp(oldType,"b3QuantizedBvhNodeData")==0)&&oldLen==20) - { - return 0; - } - if ((strcmp(oldType,"b3ShortIntIndexData")==0)) - { - int allocLen = 2; - char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; - memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1); - short* dest = (short*) dataAlloc; - const short* src = (short*) head; - for (int i=0;i<dataChunk.nr;i++) - { - dest[i] = src[i]; - if (mFlags &FD_ENDIAN_SWAP) - { - B3_SWITCH_SHORT(dest[i]); - } - } - addDataBlock(dataAlloc); - return dataAlloc; - } - } - - - - ///don't try to convert Link block data, just memcpy it. Other data can be converted. - if (strcmp("Link",oldType)!=0) - { - reverseOld = mMemoryDNA->getReverseType(oldType); - - if ((reverseOld!=-1)) - { - // make sure it's here - //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); - - // - curStruct = mMemoryDNA->getStruct(reverseOld); - newType = mMemoryDNA->getType(curStruct[0]); - curLen = mMemoryDNA->getLength(curStruct[0]); - - - - // make sure it's the same - assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); - - - // numBlocks * length - - int allocLen = (curLen); - char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; - memset(dataAlloc, 0, (dataChunk.nr*allocLen)); - - // track allocated - addDataBlock(dataAlloc); - - char *cur = dataAlloc; - char *old = head; - for (int block=0; block<dataChunk.nr; block++) - { - bool fixupPointers = true; - parseStruct(cur, old, dataChunk.dna_nr, reverseOld, fixupPointers); - mLibPointers.insert(old,(bStructHandle*)cur); - - cur += curLen; - old += oldLen; - } - return dataAlloc; - } - } else - { - //printf("Link found\n"); - } - } else - { -//#define DEBUG_EQUAL_STRUCTS -#ifdef DEBUG_EQUAL_STRUCTS - short *oldStruct; - char *oldType; - oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); - oldType = mFileDNA->getType(oldStruct[0]); - printf("%s equal structure, just memcpy\n",oldType); -#endif // - } - - - char *dataAlloc = new char[(dataChunk.len)+1]; - memset(dataAlloc, 0, dataChunk.len+1); - - - // track allocated - addDataBlock(dataAlloc); - - memcpy(dataAlloc, head, dataChunk.len); - return dataAlloc; - -} - - -// ----------------------------------------------------- // -void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers) -{ - if (old_dna == -1) return; - if (new_dna == -1) return; - - //disable this, because we need to fixup pointers/ListBase - if (0)//mFileDNA->flagEqual(old_dna)) - { - short *strc = mFileDNA->getStruct(old_dna); - int len = mFileDNA->getLength(strc[0]); - - memcpy(strcPtr, dtPtr, len); - return; - } - - // Ok, now build the struct - char *memType, *memName, *cpc, *cpo; - short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct; - int elementLength, size, revType, old_nr, new_nr, fpLen; - short firstStructType; - - - // File to memory lookup - memoryStruct = mMemoryDNA->getStruct(new_dna); - fileStruct = mFileDNA->getStruct(old_dna); - firstStruct = fileStruct; - - - filePtrOld = fileStruct; - firstStructType = mMemoryDNA->getStruct(0)[0]; - - // Get number of elements - elementLength = memoryStruct[1]; - memoryStruct+=2; - - cpc = strcPtr; cpo = 0; - for (int ele=0; ele<elementLength; ele++, memoryStruct+=2) - { - memType = mMemoryDNA->getType(memoryStruct[0]); - memName = mMemoryDNA->getName(memoryStruct[1]); - - - size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]); - revType = mMemoryDNA->getReverseType(memoryStruct[0]); - - if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*') - { - cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld); - if (cpo) - { - int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]); - old_nr = mFileDNA->getReverseType(memType); - new_nr = revType; - fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]); - if (arrayLen==1) - { - parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers); - } else - { - char* tmpCpc = cpc; - char* tmpCpo = cpo; - - for (int i=0;i<arrayLen;i++) - { - parseStruct(tmpCpc, tmpCpo, old_nr, new_nr,fixupPointers); - tmpCpc += size/arrayLen; - tmpCpo += fpLen/arrayLen; - } - } - cpc+=size; - cpo+=fpLen; - } - else - cpc+=size; - } - else - { - getMatchingFileDNA(fileStruct, memName, memType, cpc, dtPtr,fixupPointers); - cpc+=size; - } - - } -} - - -// ----------------------------------------------------- // -static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData) -{ -#define b3GetEle(value, current, type, cast, size, ptr)\ - if (strcmp(current, type)==0)\ - {\ - value = (*(cast*)ptr);\ - ptr += size;\ - } - -#define b3SetEle(value, current, type, cast, size, ptr)\ - if (strcmp(current, type)==0)\ - {\ - (*(cast*)ptr) = (cast)value;\ - ptr += size;\ - } - double value = 0.0; - - for (int i=0; i<arrayLen; i++) - { - b3GetEle(value, old, "char", char, sizeof(char), oldPtr); - b3SetEle(value, cur, "char", char, sizeof(char), curData); - b3GetEle(value, old, "short", short, sizeof(short), oldPtr); - b3SetEle(value, cur, "short", short, sizeof(short), curData); - b3GetEle(value, old, "ushort", unsigned short, sizeof(unsigned short), oldPtr); - b3SetEle(value, cur, "ushort", unsigned short, sizeof(unsigned short), curData); - b3GetEle(value, old, "int", int, sizeof(int), oldPtr); - b3SetEle(value, cur, "int", int, sizeof(int), curData); - b3GetEle(value, old, "long", int, sizeof(int), oldPtr); - b3SetEle(value, cur, "long", int, sizeof(int), curData); - b3GetEle(value, old, "float", float, sizeof(float), oldPtr); - b3SetEle(value, cur, "float", float, sizeof(float), curData); - b3GetEle(value, old, "double", double, sizeof(double), oldPtr); - b3SetEle(value, cur, "double", double, sizeof(double), curData); - } -} - - -// ----------------------------------------------------- // -void bFile::swapData(char *data, short type, int arraySize,bool ignoreEndianFlag) -{ - if (ignoreEndianFlag || (mFlags &FD_ENDIAN_SWAP)) - { - if (type == 2 || type == 3) - { - short *sp = (short*)data; - for (int i=0; i<arraySize; i++) - { - sp[0] = ChunkUtils::swapShort(sp[0]); - sp++; - } - } - if (type>3 && type <8) - { - char c; - char *cp = data; - for (int i=0; i<arraySize; i++) - { - c = cp[0]; - cp[0] = cp[3]; - cp[3] = c; - c = cp[1]; - cp[1] = cp[2]; - cp[2] = c; - cp+=4; - } - } - } -} - - - -void bFile::safeSwapPtr(char *dst, const char *src) -{ - int ptrFile = mFileDNA->getPointerSize(); - int ptrMem = mMemoryDNA->getPointerSize(); - - if (!src && !dst) - return; - - - if (ptrFile == ptrMem) - { - memcpy(dst, src, ptrMem); - } - else if (ptrMem==4 && ptrFile==8) - { - b3PointerUid* oldPtr = (b3PointerUid*)src; - b3PointerUid* newPtr = (b3PointerUid*)dst; - - if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) - { - //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers - //so it can be used to distinguish between .blend and .bullet - newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; - } else - { - //deal with pointers the Blender .blend style way, see - //readfile.c in the Blender source tree - b3Long64 longValue = *((b3Long64*)src); - //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros - if (mFlags & FD_ENDIAN_SWAP) - B3_SWITCH_LONGINT(longValue); - *((int*)dst) = (int)(longValue>>3); - } - - } - else if (ptrMem==8 && ptrFile==4) - { - b3PointerUid* oldPtr = (b3PointerUid*)src; - b3PointerUid* newPtr = (b3PointerUid*)dst; - if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) - { - newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; - newPtr->m_uniqueIds[1] = 0; - } else - { - *((b3Long64*)dst)= *((int*)src); - } - } - else - { - printf ("%d %d\n", ptrFile,ptrMem); - assert(0 && "Invalid pointer len"); - } - - -} - - -// ----------------------------------------------------- // -void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers) -{ - // find the matching memory dna data - // to the file being loaded. Fill the - // memory with the file data... - - int len = dna_addr[1]; - dna_addr+=2; - - for (int i=0; i<len; i++, dna_addr+=2) - { - const char* type = mFileDNA->getType(dna_addr[0]); - const char* name = mFileDNA->getName(dna_addr[1]); - - - - int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]); - - if ((mFlags&FD_BROKEN_DNA)!=0) - { - if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0)) - { - eleLen = 0; - } - } - - if (strcmp(lookupName, name)==0) - { - //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str()); - int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]); - //assert(arrayLenold == arrayLen); - - if (name[0] == '*') - { - // cast pointers - int ptrFile = mFileDNA->getPointerSize(); - int ptrMem = mMemoryDNA->getPointerSize(); - safeSwapPtr(strcData,data); - - if (fixupPointers) - { - if (arrayLen > 1) - { - //void **sarray = (void**)strcData; - //void **darray = (void**)data; - - char *cpc, *cpo; - cpc = (char*)strcData; - cpo = (char*)data; - - for (int a=0; a<arrayLen; a++) - { - safeSwapPtr(cpc, cpo); - m_pointerFixupArray.push_back(cpc); - cpc += ptrMem; - cpo += ptrFile; - } - } - else - { - if (name[1] == '*') - m_pointerPtrFixupArray.push_back(strcData); - else - m_pointerFixupArray.push_back(strcData); - } - } - else - { -// printf("skipped %s %s : %x\n",type.c_str(),name.c_str(),strcData); - } - - } - - else if (strcmp(type, lookupType)==0) - memcpy(strcData, data, eleLen); - else - getElement(arrayLen, lookupType, type, data, strcData); - - // -- - return; - } - data+=eleLen; - } -} - - -// ----------------------------------------------------- // -char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos) -{ - short *old = firstStruct;//mFileDNA->getStruct(old_nr); - int elementLength = old[1]; - old+=2; - - for (int i=0; i<elementLength; i++, old+=2) - { - char* type = mFileDNA->getType(old[0]); - char* name = mFileDNA->getName(old[1]); - int len = mFileDNA->getElementSize(old[0], old[1]); - - if (strcmp(lookupName, name)==0) - { - if (strcmp(type, lookupType)==0) - { - if (foundPos) - *foundPos = old; - return data; - } - return 0; - } - data+=len; - } - return 0; -} - - -// ----------------------------------------------------- // -void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag) -{ - if (dna_nr == -1) return; - - short *strc = mFileDNA->getStruct(dna_nr); - //short *firstStrc = strc; - - int elementLen= strc[1]; - strc+=2; - - short first = mFileDNA->getStruct(0)[0]; - - char *buf = data; - for (int i=0; i<elementLen; i++, strc+=2) - { - char *type = mFileDNA->getType(strc[0]); - char *name = mFileDNA->getName(strc[1]); - - int size = mFileDNA->getElementSize(strc[0], strc[1]); - if (strc[0] >= first && name[0]!='*') - { - int old_nr = mFileDNA->getReverseType(type); - int arrayLen = mFileDNA->getArraySizeNew(strc[1]); - if (arrayLen==1) - { - swapStruct(old_nr,buf,ignoreEndianFlag); - } else - { - char* tmpBuf = buf; - for (int i=0;i<arrayLen;i++) - { - swapStruct(old_nr,tmpBuf,ignoreEndianFlag); - tmpBuf+=size/arrayLen; - } - } - } - else - { - //int arrayLenOld = mFileDNA->getArraySize(name); - int arrayLen = mFileDNA->getArraySizeNew(strc[1]); - //assert(arrayLenOld == arrayLen); - swapData(buf, strc[0], arrayLen,ignoreEndianFlag); - } - buf+=size; - } -} - -void bFile::resolvePointersMismatch() -{ -// printf("resolvePointersStructMismatch\n"); - - int i; - - for (i=0;i< m_pointerFixupArray.size();i++) - { - char* cur = m_pointerFixupArray.at(i); - void** ptrptr = (void**) cur; - void* ptr = *ptrptr; - ptr = findLibPointer(ptr); - if (ptr) - { - //printf("Fixup pointer!\n"); - *(ptrptr) = ptr; - } else - { -// printf("pointer not found: %x\n",cur); - } - } - - - for (i=0; i<m_pointerPtrFixupArray.size(); i++) - { - char* cur= m_pointerPtrFixupArray.at(i); - void** ptrptr = (void**)cur; - - bChunkInd *block = m_chunkPtrPtrMap.find(*ptrptr); - if (block) - { - int ptrMem = mMemoryDNA->getPointerSize(); - int ptrFile = mFileDNA->getPointerSize(); - - - int blockLen = block->len / ptrFile; - - void *onptr = findLibPointer(*ptrptr); - if (onptr) - { - char *newPtr = new char[blockLen * ptrMem]; - addDataBlock(newPtr); - memset(newPtr, 0, blockLen * ptrMem); - - void **onarray = (void**)onptr; - char *oldPtr = (char*)onarray; - - int p = 0; - while (blockLen-- > 0) - { - b3PointerUid dp = {{0}}; - safeSwapPtr((char*)dp.m_uniqueIds, oldPtr); - - void **tptr = (void**)(newPtr + p * ptrMem); - *tptr = findLibPointer(dp.m_ptr); - - oldPtr += ptrFile; - ++p; - } - - *ptrptr = newPtr; - } - } - } -} - - -///this loop only works fine if the Blender DNA structure of the file matches the headerfiles -void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode) -{ - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - - short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); - short oldLen = fileDna->getLength(oldStruct[0]); - //char* structType = fileDna->getType(oldStruct[0]); - - char* cur = (char*)findLibPointer(dataChunk.oldPtr); - for (int block=0; block<dataChunk.nr; block++) - { - resolvePointersStructRecursive(cur,dataChunk.dna_nr, verboseMode,1); - cur += oldLen; - } -} - - -int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode,int recursion) -{ - - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - - char* memType; - char* memName; - short firstStructType = fileDna->getStruct(0)[0]; - - - char* elemPtr= strcPtr; - - short int* oldStruct = fileDna->getStruct(dna_nr); - - int elementLength = oldStruct[1]; - oldStruct+=2; - - int totalSize = 0; - - for (int ele=0; ele<elementLength; ele++, oldStruct+=2) - { - - memType = fileDna->getType(oldStruct[0]); - memName = fileDna->getName(oldStruct[1]); - - - - int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); - if (memName[0] == '*') - { - if (arrayLen > 1) - { - void **array= (void**)elemPtr; - for (int a=0; a<arrayLen; a++) - { - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - for (int i=0;i<recursion;i++) - { - printf(" "); - } - //skip the * - printf("<%s type=\"pointer\"> ",&memName[1]); - printf("%p ", array[a]); - printf("</%s>\n",&memName[1]); - } - - array[a] = findLibPointer(array[a]); - } - } - else - { - void** ptrptr = (void**) elemPtr; - void* ptr = *ptrptr; - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - for (int i=0;i<recursion;i++) - { - printf(" "); - } - printf("<%s type=\"pointer\"> ",&memName[1]); - printf("%p ", ptr); - printf("</%s>\n",&memName[1]); - } - ptr = findLibPointer(ptr); - - if (ptr) - { - // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); - *(ptrptr) = ptr; - if (memName[1] == '*' && ptrptr && *ptrptr) - { - // This will only work if the given **array is continuous - void **array= (void**)*(ptrptr); - void *np= array[0]; - int n=0; - while (np) - { - np= findLibPointer(array[n]); - if (np) array[n]= np; - n++; - } - } - } else - { - // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); - } - } - } else - { - int revType = fileDna->getReverseType(oldStruct[0]); - if (oldStruct[0]>=firstStructType) //revType != -1 && - { - char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); - - int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); - int byteOffset = 0; - - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - for (int i=0;i<recursion;i++) - { - printf(" "); - } - - if (arrayLen>1) - { - printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen); - } else - { - printf("<%s type=\"%s\">\n",cleanName,memType); - } - } - - for (int i=0;i<arrayLen;i++) - { - byteOffset += resolvePointersStructRecursive(elemPtr+byteOffset,revType, verboseMode,recursion+1); - } - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - for (int i=0;i<recursion;i++) - { - printf(" "); - } - printf("</%s>\n",cleanName); - } - } else - { - //export a simple type - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - - if (arrayLen>MAX_ARRAY_LENGTH) - { - printf("too long\n"); - } else - { - //printf("%s %s\n",memType,memName); - - bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0); - - if (isIntegerType) - { - const char* newtype="int"; - int dbarray[MAX_ARRAY_LENGTH]; - int* dbPtr = 0; - char* tmp = elemPtr; - dbPtr = &dbarray[0]; - if (dbPtr) - { - char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); - - int i; - getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); - for (i=0;i<recursion;i++) - printf(" "); - if (arrayLen==1) - printf("<%s type=\"%s\">",cleanName,memType); - else - printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); - for (i=0;i<arrayLen;i++) - printf(" %d ",dbPtr[i]); - printf("</%s>\n",cleanName); - } - } else - { - const char* newtype="double"; - double dbarray[MAX_ARRAY_LENGTH]; - double* dbPtr = 0; - char* tmp = elemPtr; - dbPtr = &dbarray[0]; - if (dbPtr) - { - int i; - getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); - for (i=0;i<recursion;i++) - printf(" "); - char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); - - if (arrayLen==1) - { - printf("<%s type=\"%s\">",memName,memType); - } - else - { - printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); - } - for (i=0;i<arrayLen;i++) - printf(" %f ",dbPtr[i]); - printf("</%s>\n",cleanName); - } - } - } - - } - } - } - - int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]); - totalSize += size; - elemPtr+=size; - - } - - return totalSize; -} - - -///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures -void bFile::resolvePointers(int verboseMode) -{ - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - - //char *dataPtr = mFileBuffer+mDataStart; - - if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) - { - resolvePointersMismatch(); - } - - { - - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); - int numitems = m_chunks.size(); - printf("<bullet_physics version=%d itemcount = %d>\n", b3GetVersion(), numitems); - } - for (int i=0;i<m_chunks.size();i++) - { - const bChunkInd& dataChunk = m_chunks.at(i); - - if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr)) - { - //dataChunk.len - short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); - char* oldType = fileDna->getType(oldStruct[0]); - - if (verboseMode & FD_VERBOSE_EXPORT_XML) - printf(" <%s pointer=%p>\n",oldType,dataChunk.oldPtr); - - resolvePointersChunk(dataChunk, verboseMode); - - if (verboseMode & FD_VERBOSE_EXPORT_XML) - printf(" </%s>\n",oldType); - } else - { - //printf("skipping mStruct\n"); - } - } - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - printf("</bullet_physics>\n"); - } - } - - -} - - -// ----------------------------------------------------- // -void* bFile::findLibPointer(void *ptr) -{ - - bStructHandle** ptrptr = getLibPointers().find(ptr); - if (ptrptr) - return *ptrptr; - return 0; -} - - -void bFile::updateOldPointers() -{ - int i; - - for (i=0;i<m_chunks.size();i++) - { - bChunkInd& dataChunk = m_chunks[i]; - dataChunk.oldPtr = findLibPointer(dataChunk.oldPtr); - } -} -void bFile::dumpChunks(bParse::bDNA* dna) -{ - int i; - - for (i=0;i<m_chunks.size();i++) - { - bChunkInd& dataChunk = m_chunks[i]; - char* codeptr = (char*)&dataChunk.code; - char codestr[5] = {codeptr[0],codeptr[1],codeptr[2],codeptr[3],0}; - - short* newStruct = dna->getStruct(dataChunk.dna_nr); - char* typeName = dna->getType(newStruct[0]); - printf("%3d: %s ",i,typeName); - - printf("code=%s ",codestr); - - printf("ptr=%p ",dataChunk.oldPtr); - printf("len=%d ",dataChunk.len); - printf("nr=%d ",dataChunk.nr); - if (dataChunk.nr!=1) - { - printf("not 1\n"); - } - printf("\n"); - - - - - } - -#if 0 - IDFinderData ifd; - ifd.success = 0; - ifd.IDname = NULL; - ifd.just_print_it = 1; - for (i=0; i<bf->m_blocks.size(); ++i) - { - BlendBlock* bb = bf->m_blocks[i]; - printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size()); - block_ID_finder(bb, bf, &ifd); - printf("\n"); - } -#endif - -} - - -void bFile::writeChunks(FILE* fp, bool fixupPointers) -{ - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - - for (int i=0;i<m_chunks.size();i++) - { - bChunkInd& dataChunk = m_chunks.at(i); - - // Ouch! need to rebuild the struct - short *oldStruct,*curStruct; - char *oldType, *newType; - int oldLen, curLen, reverseOld; - - oldStruct = fileDna->getStruct(dataChunk.dna_nr); - oldType = fileDna->getType(oldStruct[0]); - oldLen = fileDna->getLength(oldStruct[0]); - ///don't try to convert Link block data, just memcpy it. Other data can be converted. - reverseOld = mMemoryDNA->getReverseType(oldType); - - - if ((reverseOld!=-1)) - { - // make sure it's here - //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); - // - curStruct = mMemoryDNA->getStruct(reverseOld); - newType = mMemoryDNA->getType(curStruct[0]); - // make sure it's the same - assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); - - - curLen = mMemoryDNA->getLength(curStruct[0]); - dataChunk.dna_nr = reverseOld; - if (strcmp("Link",oldType)!=0) - { - dataChunk.len = curLen * dataChunk.nr; - } else - { -// printf("keep length of link = %d\n",dataChunk.len); - } - - //write the structure header - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - - - - short int* curStruct1; - curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr); - assert(curStruct1 == curStruct); - - char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr; - - //write the actual contents of the structure(s) - fwrite(cur,dataChunk.len,1,fp); - } else - { - printf("serious error, struct mismatch: don't write\n"); - } - } - -} - - -// ----------------------------------------------------- // -int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) -{ - bool swap = false; - bool varies = false; - - if (flags &FD_ENDIAN_SWAP) - swap = true; - if (flags &FD_BITS_VARIES) - varies = true; - - if (VOID_IS_8) - { - if (varies) - { - bChunkPtr4 head; - memcpy(&head, dataPtr, sizeof(bChunkPtr4)); - - - bChunkPtr8 chunk; - - chunk.code = head.code; - chunk.len = head.len; - chunk.m_uniqueInts[0] = head.m_uniqueInt; - chunk.m_uniqueInts[1] = 0; - chunk.dna_nr = head.dna_nr; - chunk.nr = head.nr; - - if (swap) - { - if ((chunk.code & 0xFFFF)==0) - chunk.code >>=16; - - B3_SWITCH_INT(chunk.len); - B3_SWITCH_INT(chunk.dna_nr); - B3_SWITCH_INT(chunk.nr); - } - - - memcpy(dataChunk, &chunk, sizeof(bChunkInd)); - } - else - { - bChunkPtr8 c; - memcpy(&c, dataPtr, sizeof(bChunkPtr8)); - - if (swap) - { - if ((c.code & 0xFFFF)==0) - c.code >>=16; - - B3_SWITCH_INT(c.len); - B3_SWITCH_INT(c.dna_nr); - B3_SWITCH_INT(c.nr); - } - - memcpy(dataChunk, &c, sizeof(bChunkInd)); - } - } - else - { - if (varies) - { - bChunkPtr8 head; - memcpy(&head, dataPtr, sizeof(bChunkPtr8)); - - - bChunkPtr4 chunk; - chunk.code = head.code; - chunk.len = head.len; - - if (head.m_uniqueInts[0]==head.m_uniqueInts[1]) - { - chunk.m_uniqueInt = head.m_uniqueInts[0]; - } else - { - b3Long64 oldPtr =0; - memcpy(&oldPtr, &head.m_uniqueInts[0], 8); - if (swap) - B3_SWITCH_LONGINT(oldPtr); - chunk.m_uniqueInt = (int)(oldPtr >> 3); - } - - - chunk.dna_nr = head.dna_nr; - chunk.nr = head.nr; - - if (swap) - { - if ((chunk.code & 0xFFFF)==0) - chunk.code >>=16; - - B3_SWITCH_INT(chunk.len); - B3_SWITCH_INT(chunk.dna_nr); - B3_SWITCH_INT(chunk.nr); - } - - memcpy(dataChunk, &chunk, sizeof(bChunkInd)); - } - else - { - bChunkPtr4 c; - memcpy(&c, dataPtr, sizeof(bChunkPtr4)); - - if (swap) - { - if ((c.code & 0xFFFF)==0) - c.code >>=16; - - B3_SWITCH_INT(c.len); - B3_SWITCH_INT(c.dna_nr); - B3_SWITCH_INT(c.nr); - } - memcpy(dataChunk, &c, sizeof(bChunkInd)); - } - } - - if (dataChunk->len < 0) - return -1; - -#if 0 - print ("----------"); - print (dataChunk->code); - print (dataChunk->len); - print (dataChunk->old); - print (dataChunk->dna_nr); - print (dataChunk->nr); -#endif - return (dataChunk->len+ChunkUtils::getOffset(flags)); -} - - - -//eof |