/* Copyright (C) 2006 Charlie C * * 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 #include "bDNA.h" #include "bBlenderFile.h" #include "btBulletFile.h" #include "LinearMath/btSerializer.h" #include "bCommon.h" #include #include #include bool isBulletFile = true; using namespace bParse; typedef std::string bString; /////////////////////////////////////////////////////////////////////////////// typedef std::map bStringMap; typedef std::vector bVariableList; typedef std::vector bStringList; /////////////////////////////////////////////////////////////////////////////// static FILE *dump = 0; static bDNA *mDNA = 0; static bStringMap mStructs; /////////////////////////////////////////////////////////////////////////////// class bVariable { public: bVariable(); ~bVariable(); bString dataType; bString variableName; bString functionName; bString classCtor; bString memberVariable; bString memberDataType; bString functionArgs; void initialize(bString dataType, bString variable, bStringMap refDataTable); bool isPtr; bool isFunctionPtr; bool isPtrToPtr; bool isArray; bool isCharArray; bool isListBase; bool isPadding; bool isCommentedOut; bool isGeneratedType; bool isbString; }; /////////////////////////////////////////////////////////////////////////////// bool dataTypeStandard(bString dataType) { if (dataType == "char") return true; if (dataType == "short") return true; if (dataType == "int") return true; if (dataType == "long") return true; if (dataType == "float") return true; if (dataType == "double") return true; if (dataType == "void") return true; if (dataType == "btScalar") return true; return false; } /////////////////////////////////////////////////////////////////////////////// void writeTemplate(short *structData) { bString type = mDNA->getType(structData[0]); bString className = type; bString prefix = isBulletFile ? "bullet_" : "blender_"; int thisLen = structData[1]; structData += 2; bString fileName = prefix + type; bVariableList dataTypes; bStringMap includeFiles; for (int dataVal = 0; dataVal < thisLen; dataVal++, structData += 2) { bString dataType = mDNA->getType(structData[0]); bString dataName = mDNA->getName(structData[1]); { bString newDataType = ""; bString newDataName = ""; bStringMap::iterator addB = mStructs.find(dataType); if (addB != mStructs.end()) { newDataType = addB->second; newDataName = dataName; } else { if (dataTypeStandard(dataType)) { newDataType = dataType; newDataName = dataName; } else { // Unresolved // set it to an empty struct // if it's not a ptr generate an error newDataType = "bInvalidHandle"; newDataName = dataName; if (dataName[0] != '*') { } } } if (!newDataType.empty() && !newDataName.empty()) { bVariable var = bVariable(); var.initialize(newDataType, newDataName, mStructs); dataTypes.push_back(var); } } bStringMap::iterator include = mStructs.find(dataType); if (include != mStructs.end()) { if (dataName[0] != '*') { if (includeFiles.find(dataType) == includeFiles.end()) { includeFiles[dataType] = prefix + dataType; } } } } fprintf(dump, "###############################################################\n"); fprintf(dump, "%s = bStructClass()\n", fileName.c_str()); fprintf(dump, "%s.name = '%s'\n", fileName.c_str(), className.c_str()); fprintf(dump, "%s.filename = '%s'\n", fileName.c_str(), fileName.c_str()); bVariableList::iterator vars = dataTypes.begin(); while (vars != dataTypes.end()) { fprintf(dump, "%s.dataTypes.append('%s %s')\n", fileName.c_str(), vars->dataType.c_str(), vars->variableName.c_str()); vars++; } bStringMap::iterator inc = includeFiles.begin(); while (inc != includeFiles.end()) { fprintf(dump, "%s.includes.append('%s.h')\n", fileName.c_str(), inc->second.c_str()); inc++; } fprintf(dump, "DataTypeList.append(%s)\n", fileName.c_str()); } /////////////////////////////////////////////////////////////////////////////// char data[] = { "\n" "class bStructClass:\n" " def __init__(self):\n" " self.name = \"\";\n" " self.filename = \"\";\n" " self.includes = []\n" " self.dataTypes = []\n" "\n\n" "DataTypeList = []\n"}; /////////////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { using namespace bParse; dump = fopen("dump.py", "w"); if (!dump) return 0; fprintf(dump, "%s\n", data); #if 0 char* filename = "../../../../data/r2d2_multibody.bullet"; if (argc==2) filename = argv[1]; bString fileStr(filename); bString extension(".bullet"); int index2 = fileStr.find(extension); if (index2>=0) isBulletFile=true; FILE* fp = fopen (filename,"rb"); if (!fp) { printf("error: file not found %s\n",filename); exit(0); } char* memBuf = 0; int len = 0; long currentpos = ftell(fp); /* save current cursor position */ long newpos; int bytesRead; fseek(fp, 0, SEEK_END); /* seek to end */ newpos = ftell(fp); /* find position of end -- this is the length */ fseek(fp, currentpos, SEEK_SET); /* restore previous cursor position */ len = newpos; memBuf = (char*)malloc(len); bytesRead = fread(memBuf,len,1,fp); bool swap = false; if (isBulletFile) { btBulletFile f(memBuf,len); swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0; } else { bBlenderFile f(memBuf,len); swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0; } #else isBulletFile = true; bool swap = false; char *memBuf = sBulletDNAstr; int len = sBulletDNAlen; #endif char *blenderData = memBuf; int sdnaPos = 0; int mDataStart = 12; char *tempBuffer = blenderData; for (int i = 0; i < len; i++) { // looking for the data's starting position // and the start of SDNA decls if (!mDataStart && strncmp(tempBuffer, "REND", 4) == 0) mDataStart = i; if (!sdnaPos && strncmp(tempBuffer, "SDNA", 4) == 0) sdnaPos = i; if (mDataStart && sdnaPos) break; tempBuffer++; } FILE *fpdna = fopen("dnaString.txt", "w"); char buf[1024]; for (int i = 0; i < len - sdnaPos; i++) { int dnaval = (memBuf + sdnaPos)[i]; if ((i % 32) == 0) { sprintf(buf, "%d,\n", dnaval); } else { sprintf(buf, "%d,", dnaval); } fwrite(buf, strlen(buf), 1, fpdna); } fclose(fpdna); mDNA = new bDNA(); //mDNA->initMemory(); mDNA->init(memBuf + sdnaPos, len - sdnaPos, swap); for (int i = 0; i < mDNA->getNumStructs(); i++) { short *structData = mDNA->getStruct(i); bString type = mDNA->getType(structData[0]); bString className = type; mStructs[type] = className; } for (int i = 0; i < mDNA->getNumStructs(); i++) { short *structData = mDNA->getStruct(i); writeTemplate(structData); } delete mDNA; fclose(dump); return 0; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// int _getArraySize(char *str) { int a, mul = 1; char stri[100], *cp = 0; int len = (int)strlen(str); memcpy(stri, str, len + 1); for (a = 0; a < len; a++) { if (str[a] == '[') cp = &(stri[a + 1]); else if (str[a] == ']' && cp) { stri[a] = 0; mul *= atoi(cp); } } return mul; } /////////////////////////////////////////////////////////////////////////////// bVariable::bVariable() : dataType("invalid"), variableName("invalid"), functionName(""), classCtor(""), memberVariable(""), memberDataType(""), functionArgs(""), isPtr(false), isFunctionPtr(false), isPtrToPtr(false), isArray(false), isCharArray(false), isListBase(false), isPadding(false), isCommentedOut(false), isGeneratedType(false), isbString(false) { } /////////////////////////////////////////////////////////////////////////////// bVariable::~bVariable() { dataType.clear(); variableName.clear(); } /////////////////////////////////////////////////////////////////////////////// void bVariable::initialize(bString type, bString variable, bStringMap refDataTable) { dataType = type; variableName = variable; if (variableName[0] == '*') { isPtr = true; if (variableName[1] == '*') isPtrToPtr = true; } if (variableName[0] == '(') if (variableName[1] == '*') isFunctionPtr = true; if (variableName[variableName.size() - 1] == ']') { isArray = true; if (type == "char") isCharArray = true; } if (type == "ListBase") isListBase = true; if (variableName[0] == 'p') { bString sub = variableName.substr(0, 3); if (sub == "pad") isPadding = true; } if (dataType[0] == '/' && dataType[1] == '/') isCommentedOut = true; if (refDataTable.find(dataType) != refDataTable.end()) isGeneratedType = true; if (!isBulletFile) { // replace valid float arrays if (dataType == "float" && isArray) { int size = _getArraySize((char *)variableName.c_str()); if (size == 3) { dataType = "vec3f"; variableName = variableName.substr(0, variableName.find_first_of("[")); } if (size == 4) { dataType = "vec4f"; variableName = variableName.substr(0, variableName.find_first_of("[")); } } } memberDataType = dataType; functionArgs = variableName; } // eof