void convert::replaceAllStringInFile(const std::string& oldfilename, const std::string& newfilename, const std::string& oldstring, const std::string& newstring) { std::string s = readStringFromFile(oldfilename); if (s.length() <= 0) { return; } replaceAllString(s, oldstring, newstring); writeStringToFile(s, newfilename); }
void ModelMaker::run() { if(mYamlFileLocation.length() < 1){ DS_LOG_WARNING("No file specified in model maker"); return; } std::cout << "Parsing yaml file: " << mYamlFileLocation << std::endl; mYamlLoadService.mFileLocation = mYamlFileLocation; mYamlLoadService.run(); std::vector<ModelModel> models = mYamlLoadService.mOutput; if(models.empty()){ DS_LOG_WARNING("No valid models loaded in model maker."); return; } for(auto it = models.begin(); it < models.end(); ++it){ ModelModel& mm = (*it); // make the first letter of the table name uppercase std::string tableName = mm.getTableName(); if(tableName.empty()){ DS_LOG_WARNING("Model maker got a blank table!"); continue; } std::transform(tableName.begin(), tableName.begin() + 1, tableName.begin(), ::toupper); // push all the nearby getters/setters/members into stringstreams // headers std::stringstream sCustomIncludes; std::stringstream sCustomForwardDeclares; std::stringstream sHeaderGetters; std::stringstream sHeaderSetters; // imps std::stringstream sCustomImpIncludes; std::stringstream sDataMembers; std::stringstream sCustomEmptyData; std::stringstream sImpGetters; std::stringstream sImpSetters; // strings for each column std::string thisHeaderGetter; std::string thisHeaderSetter; std::string thisEmptyData; std::string thisDataMember; std::string thisImpGetter; std::string thisImpSetter; std::map<std::string, std::string> dataMemberInitializers; // make all 'resource' flagged columns into proper resources for(auto mit = mm.getResourceColumns().begin(); mit < mm.getResourceColumns().end(); ++mit){ for(auto cit = mm.getColumns().begin(); cit < mm.getColumns().end(); ++cit){ // if this column is the resource one, set it's type to resource and move on if((*cit).getColumnName() == (*mit) && ((*cit).getType() == ModelColumn::Integer || (*cit).getType() == ModelColumn::UnsignedInt)) { ModelColumn* mc = const_cast<ModelColumn*>(&(*cit)); if(mc){ mc->setType(ModelColumn::Resource); } break; } } } // add special columns for all relations for(auto rit = mm.getRelations().begin(); rit < mm.getRelations().end(); ++rit){ const ModelRelation& mr = (*rit); if(mr.getType() == ModelRelation::Invalid) continue; // create the class name out of the foreign table name, e.g. StoryRef std::string foreignTable = mr.getForeignKeyTable(); std::transform(foreignTable.begin(), foreignTable.begin() + 1, foreignTable.begin(), ::toupper); std::stringstream foreignClass; foreignClass << foreignTable << "Ref"; // create the empty data name from the class name. e.g. EMPTY_STORY or EMPTY_STORY_ELEMENT_VECTOR std::string foreignEmptyType = foreignClass.str(); std::transform(foreignEmptyType.begin(), foreignEmptyType.end(), foreignEmptyType.begin(), ::toupper); std::stringstream foreignEmptyTypeFull; foreignEmptyTypeFull << foreignEmptyType; std::stringstream foreignDataType; if(mr.getType() == ModelRelation::Many){ foreignEmptyTypeFull << "_VECTOR"; foreignDataType << "std::vector<" << foreignClass.str() << ">"; // the 'many' types need to have a header include sCustomIncludes << "#include \"" << getFileName(mr.getForeignKeyTable(), true) << "\"" << std::endl; } else { foreignDataType << foreignClass.str(); // single types need to be forward declared to avoid circular refs sCustomForwardDeclares << "class " << foreignClass.str() << ";" << std::endl; sCustomImpIncludes << "#include \"" << getFileName(mr.getForeignKeyTable(), true) << "\"" << std::endl; } ModelColumn mc; mc.setColumnName(foreignClass.str()); mc.setType(ModelColumn::Custom); mc.setCustomDataType(foreignDataType.str()); mc.setCustomEmptyDataName(foreignEmptyTypeFull.str()); mm.addColumn(mc); } // add the getters, setters, empty data and data members for each column to the stringstreams for(auto cit = mm.getColumns().begin(); cit < mm.getColumns().end(); ++cit){ thisHeaderGetter = headerGetter; thisHeaderSetter = headerSetter; thisEmptyData = ""; thisDataMember = dataMember; thisImpGetter = impGetter; thisImpSetter = impSetter; std::string dataType = ""; const ModelColumn& mc = (*cit); // invalid columns get tossed if(mc.getType() == ModelColumn::Invalid){ continue; // if it's an int, check for unsigned int too } else if(mc.getType() == ModelColumn::Integer || mc.getType() == ModelColumn::UnsignedInt){ if(mc.getIsUnsigned()){ dataType = uintDataType; thisEmptyData = "UINT"; } else { dataType = intDataType; thisEmptyData = "INT"; } } else if(mc.getType() == ModelColumn::Float){ dataType = floatDataType; thisEmptyData = "FLOAT"; } else if(mc.getType() == ModelColumn::String){ dataType = stringDataType; thisEmptyData = "WSTRING"; } else if(mc.getType() == ModelColumn::Resource){ dataType = resourceDataType; thisEmptyData = "RESOURCE"; } else if(mc.getType() == ModelColumn::Custom){ dataType = mc.getCustomDataType(); thisEmptyData = mc.getCustomEmptyDataName(); sCustomEmptyData << "const " << mc.getCustomDataType() << " EMPTY_" << mc.getCustomEmptyDataName() << ";" << std::endl; } std::string columnName = mc.getColumnName(); std::transform(columnName.begin(), columnName.begin() + 1, columnName.begin(), ::toupper); dataMemberInitializers[columnName] = thisEmptyData; thisImpGetter = replaceAllString(thisImpGetter, "EMPTYDATATYPE", thisEmptyData); thisHeaderGetter = replaceAllString(thisHeaderGetter, "DATA_TYPE", dataType); thisHeaderSetter = replaceAllString(thisHeaderSetter, "DATA_TYPE", dataType); thisDataMember = replaceAllString(thisDataMember, "DATA_TYPE", dataType); thisImpGetter = replaceAllString(thisImpGetter, "DATA_TYPE", dataType); thisImpSetter = replaceAllString(thisImpSetter, "DATA_TYPE", dataType); sHeaderGetters << replaceAllString(thisHeaderGetter, "ColumnName", columnName) << std::endl; sHeaderSetters << replaceAllString(thisHeaderSetter, "ColumnName", columnName) << std::endl; sDataMembers << replaceAllString(thisDataMember, "ColumnName", columnName) << std::endl; sImpGetters << replaceAllString(thisImpGetter, "ColumnName", columnName) << std::endl; sImpSetters << replaceAllString(thisImpSetter, "ColumnName", columnName) << std::endl; } // add initializers to empty data when Data() is constructed std::stringstream memberInitializers; bool firstInitializer = true; for(auto it = dataMemberInitializers.begin(); it != dataMemberInitializers.end(); ++it){ if(firstInitializer){ memberInitializers << "\t: m"; firstInitializer = false; } else { memberInitializers << "\t, m"; } memberInitializers << it->first << "(EMPTY_" << it->second << ")\n"; } // add all the stringstreams to the header and put in the table name / model name std::string header = baseHeader; header = replaceAllString(header, "FORWARD_DECLARES", sCustomForwardDeclares.str()); header = replaceAllString(header, "CUSTOM_INCLUDES", sCustomIncludes.str()); header = replaceAllString(header, "COLUMN_GETTERS", sHeaderGetters.str()); header = replaceAllString(header, "COLUMN_SETTERS", sHeaderSetters.str()); header = replaceAllString(header, "TableName", tableName); //std::cout << std::endl << std::endl << header << std::endl << std::endl; std::string imp = baseCpp; imp = replaceAllString(imp, "CUSTOM_INCLUDES", sCustomImpIncludes.str()); imp = replaceAllString(imp, "CUSTOM_EMPTY_DATA", sCustomEmptyData.str()); imp = replaceAllString(imp, "INITIALIZE_DATA_MEMBERS", memberInitializers.str()); imp = replaceAllString(imp, "DATA_MEMBERS", sDataMembers.str()); imp = replaceAllString(imp, "IMP_GETTERS", sImpGetters.str()); imp = replaceAllString(imp, "IMP_SETTERS", sImpSetters.str()); imp = replaceAllString(imp, "TableName", tableName); // std::cout << std::endl << std::endl << imp << std::endl << std::endl; // write out the header and implementation std::stringstream filename; filename << "%APP%/generated/" << getFileName(mm.getTableName(), true); std::cout << "Writing header to: " << filename.str() << std::endl; std::ofstream headerWriter; headerWriter.open(ds::Environment::expand(filename.str())); headerWriter << header; headerWriter.close(); filename.str(""); filename << "%APP%/generated/" << getFileName(mm.getTableName(), false); std::cout << "Writing implementation to: " << filename.str() << std::endl; std::ofstream impWriter; impWriter.open(ds::Environment::expand(filename.str())); impWriter << imp; impWriter.close(); } }
void Exporter::exportMaterial(const aiMaterial& mtl) const { std::string diffTex; std::string normTex; std::string specColTex; std::string shininessTex; std::string dispTex; std::string emissiveTex; std::string metallicTex; aiString path; std::string name = getMaterialName(mtl); LOGI("Exporting material %s", name.c_str()); // Diffuse texture if(mtl.GetTextureCount(aiTextureType_DIFFUSE) > 0) { if(mtl.GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS) { diffTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Normal texture if(mtl.GetTextureCount(aiTextureType_NORMALS) > 0) { if(mtl.GetTexture(aiTextureType_NORMALS, 0, &path) == AI_SUCCESS) { normTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Specular color if(mtl.GetTextureCount(aiTextureType_SPECULAR) > 0) { if(mtl.GetTexture(aiTextureType_SPECULAR, 0, &path) == AI_SUCCESS) { specColTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Shininess color if(mtl.GetTextureCount(aiTextureType_SHININESS) > 0) { if(mtl.GetTexture(aiTextureType_SHININESS, 0, &path) == AI_SUCCESS) { shininessTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Height texture if(mtl.GetTextureCount(aiTextureType_DISPLACEMENT) > 0) { if(mtl.GetTexture(aiTextureType_DISPLACEMENT, 0, &path) == AI_SUCCESS) { dispTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Emissive texture if(mtl.GetTextureCount(aiTextureType_EMISSIVE) > 0) { if(mtl.GetTexture(aiTextureType_EMISSIVE, 0, &path) == AI_SUCCESS) { emissiveTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Metallic texture if(mtl.GetTextureCount(aiTextureType_REFLECTION) > 0) { if(mtl.GetTexture(aiTextureType_REFLECTION, 0, &path) == AI_SUCCESS) { metallicTex = getFilename(path.C_Str()); } else { ERROR("Failed to retrieve texture"); } } // Write file static const char* diffNormSpecFragTemplate = #include "templates/diffNormSpecFrag.h" ; static const char* simpleVertTemplate = #include "templates/simpleVert.h" ; static const char* tessVertTemplate = #include "templates/tessVert.h" ; static const char* readRgbFromTextureTemplate = R"( <operation> <id>%id%</id> <returnType>vec3</returnType> <function>readRgbFromTexture</function> <arguments> <argument>%map%</argument> <argument>out2</argument> </arguments> </operation>)"; static const char* readRFromTextureTemplate = R"( <operation> <id>%id%</id> <returnType>float</returnType> <function>readRFromTexture</function> <arguments> <argument>%map%</argument> <argument>out2</argument> </arguments> </operation>)"; // Compose full template // First geometry part std::string materialStr; materialStr = R"(<?xml version="1.0" encoding="UTF-8" ?>)"; materialStr += "\n<material>\n\t<programs>\n"; if(/*dispTex.empty()*/ 1) { materialStr += simpleVertTemplate; } else { materialStr += tessVertTemplate; } materialStr += "\n"; // Then fragment part materialStr += diffNormSpecFragTemplate; materialStr += "\n\t</programs>\t</material>"; // Replace strings if(!dispTex.empty()) { materialStr = replaceAllString(materialStr, "%dispMap%", m_texrpath + dispTex); } // Diffuse if(!diffTex.empty()) { materialStr = replaceAllString(materialStr, "%diffuseColorInput%", R"(<input><type>sampler2D</type><name>uDiffuseColor</name><value>)" + m_texrpath + diffTex + R"(</value></input>)"); materialStr = replaceAllString(materialStr, "%diffuseColorFunc%", readRgbFromTextureTemplate); materialStr = replaceAllString(materialStr, "%id%", "10"); materialStr = replaceAllString(materialStr, "%map%", "uDiffuseColor"); materialStr = replaceAllString(materialStr, "%diffuseColorArg%", "out10"); }