std::shared_ptr<Model<Vertex3DNormTex>> ModelLoader::load(const std::string &filePath, float scale, bool deleteLocalData) { std::ifstream f(filePath); if (f.fail()) { std::ostringstream oStringStream; oStringStream << "couldn't open " << filePath << std::endl; log(oStringStream.str()); return std::shared_ptr<Model<Vertex3DNormTex>>(); } else { f.close(); } const aiScene *scene = importer.ReadFile(filePath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality); if (scene == nullptr) { log(importer.GetErrorString()); } std::map<std::string, std::shared_ptr<Texture>> textures(loadTextures(scene, filePath)); std::vector<std::shared_ptr<Material>> materials(loadMaterials(scene, textures)); const aiNode *rootNode = scene->mRootNode; std::shared_ptr<Model<Vertex3DNormTex>> output(std::make_shared<Model<Vertex3DNormTex>>()); addMeshesFromNode(scene, rootNode, glm::scale(glm::mat4(), glm::vec3(scale)), output, materials, scale, deleteLocalData); return output; }
bool Sprite3D::loadFromFile(const std::string& path, NodeDatas* nodedatas, MeshDatas* meshdatas, MaterialDatas* materialdatas) { std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path); std::string ext = path.substr(path.length() - 4, 4); std::transform(ext.begin(), ext.end(), ext.begin(), tolower); if (ext == ".obj") { return Bundle3D::loadObj(*meshdatas, *materialdatas, *nodedatas, fullPath); } else if (ext == ".c3b" || ext == ".c3t") { //load from .c3b or .c3t auto bundle = Bundle3D::createBundle(); if (!bundle->load(fullPath)) { Bundle3D::destroyBundle(bundle); return false; } auto ret = bundle->loadMeshDatas(*meshdatas) && bundle->loadMaterials(*materialdatas) && bundle->loadNodes(*nodedatas); Bundle3D::destroyBundle(bundle); return ret; } return false; }
void AssetImporter::importScene( ID3D11Device* d3dDevice, std::wstring& path, GRAPHICS::Scene& outScene ) { Assimp::Importer importer; std::string assetPath(path.begin(), path.end()); const aiScene* scene = importer.ReadFile(assetPath.c_str(), aiProcess_ConvertToLeftHanded | aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_FlipWindingOrder | aiProcess_GenUVCoords | aiProcess_GenSmoothNormals | aiProcess_SortByPType); if (!scene) { printf("Failed to import asset: %s", assetPath.c_str()); } GRAPHICS::RESOURCES::Mesh* meshArr = loadMeshes(d3dDevice, scene); GRAPHICS::RESOURCES::Material* materialArr = loadMaterials(d3dDevice, scene); nextNode(d3dDevice, scene, scene->mRootNode, scene->mRootNode->mTransformation, meshArr, materialArr, outScene); loadLights(d3dDevice, outScene, scene); delete[] meshArr; delete[] materialArr; }
//------------------------------------------------------ void MaterialService::onDBLoad(const FileGroupPtr& db, uint32_t curmask) { LOG_INFO("MaterialService::onDBLoad called."); // see if we're facing a mission file if (curmask & DBM_MIS_DATA) loadMaterials(db); }
bool Sprite3D::loadFromC3x(const std::string& path) { std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path); //load from .c3b or .c3t auto bundle = Bundle3D::getInstance(); if (!bundle->load(fullPath)) return false; MeshDatas meshdatas; MaterialDatas* materialdatas = new (std::nothrow) MaterialDatas(); NodeDatas* nodeDatas = new (std::nothrow) NodeDatas(); if (bundle->loadMeshDatas(meshdatas) && bundle->loadMaterials(*materialdatas) && bundle->loadNodes(*nodeDatas) && initFrom(*nodeDatas, meshdatas, *materialdatas)) { //add to cache auto data = new (std::nothrow) Sprite3DCache::Sprite3DData(); data->materialdatas = materialdatas; data->nodedatas = nodeDatas; data->meshVertexDatas = _meshVertexDatas; for (const auto mesh : _meshes) { data->glProgramStates.pushBack(mesh->getGLProgramState()); } Sprite3DCache::getInstance()->addSprite3DData(path, data); return true; } delete materialdatas; delete nodeDatas; return false; }
bool Model::loadObject(string name) { filename = name; ifstream istr(filename.data()); if(!istr) return false; deleteObjects(); displayList = 0; objectLoaded = false; GroupObject* defaultObject = new GroupObject; GroupObject* currentObject = defaultObject; objects.push_back(defaultObject); // some playing with strings to get just the file path char path[256]; strcpy(path, filename.data()); for(int i = (int)filename.length(); path[i] != '\\' && path[i] != '/'; i--) path[i] = 0; Material* currentMaterial = NULL; char line[256]; // loop through every line of the .obj file while(istr.getline(line, 256)) { // some .obj exporters put a space a the end of the line - if so, we trim it here string temp = string(line); if(temp.size() > 0 && temp.at(temp.length() - 1) == ' ') temp.erase(temp.size() - 1, 1); istringstream newLine(temp, istringstream::in); string firstWord; newLine >> firstWord; if(firstWord == "#") { // do nothing for comments } else if(firstWord == "mtllib") { string materialFilename; while(newLine >> materialFilename) { loadMaterials(string(path) + materialFilename); } } else if(firstWord == "usemtl")
std::string MaterialSystem::getBlock (const std::string& texture) { if (texture.empty()) return ""; const std::string textureDir = GlobalTexturePrefix_get(); std::string skippedTextureDirectory = texture.substr(textureDir.length()); if (skippedTextureDirectory.empty()) return ""; MaterialBlockMap::iterator i = _blocks.find(skippedTextureDirectory); if (i != _blocks.end()) return i->second; if (!_materialLoaded) loadMaterials(); if (!_materialLoaded) return ""; StringOutputStream outputStream; StringInputStream inputStream(_material); AutoPtr<Tokeniser> tokeniser(GlobalScriptLibrary().createSimpleTokeniser(inputStream)); int depth = 0; bool found = false; std::string token = tokeniser->getToken(); while (token.length()) { if (token == "{") { depth++; } else if (token == "}") { depth--; } if (depth >= 1) { if (depth == 1 && token == "material") { token = tokeniser->getToken(); if (token == skippedTextureDirectory) { found = true; outputStream << "{ material "; } } if (found) outputStream << token << " "; } else if (found) { outputStream << "}"; break; } token = tokeniser->getToken(); } return outputStream.toString(); }
bool model::loadMaterialLib(FILE * file) { char * wd = strtok(filename, "/"); char buffer[256]; fscanf(file, "%s", buffer); sprintf(mtllib, "%s/%s", wd, buffer); strcpy(directory, wd); FILE * lib = fopen(buffer, "r"); if(lib == NULL) { MessageBox(NULL, mtllib, "Material library not found:", MB_OK); return false; } else loadMaterials(lib); fclose(lib); return true; }
void MaterialSystem::generateMaterialFromTexture () { if (GlobalMap().isUnnamed()) { // save the map first gtkutil::errorDialog(_("You have to save your map before material generation can work")); return; } loadMaterials(); if (!_materialLoaded) return; const std::string textureDir = GlobalTexturePrefix_get(); std::string append = ""; if (GlobalSelectionSystem().areFacesSelected()) { for (FaceInstancesList::iterator i = g_SelectedFaceInstances.m_faceInstances.begin(); i != g_SelectedFaceInstances.m_faceInstances.end(); ++i) { const FaceInstance& faceInstance = *(*i); const Face &face = faceInstance.getFace(); const std::string& texture = face.GetShader(); // don't generate materials for common textures if (texture.find("tex_common") != std::string::npos) continue; std::string skippedTextureDirectory = texture.substr(textureDir.length()); std::string materialDefinition = "material " + skippedTextureDirectory; /* check whether there is already an entry for the selected texture */ if (_material.find(materialDefinition) == std::string::npos) { std::stringstream os; ContentsFlagsValue flags; ContentsFlagsValue faceFlags(face.GetFlags()); os << "{" << std::endl; os << "\t" << materialDefinition << std::endl; os << "\t{" << std::endl; generateMaterialForFace(flags.getContentFlags(), flags.getSurfaceFlags(), skippedTextureDirectory, os); os << "\t}" << std::endl; os << "}" << std::endl; append += os.str(); } } } showMaterialDefinitionAndAppend(append); }
bool Materials::unserializeMaterials(const FileName& filename, xmlNodePtr root, wxString& error, wxArrayString& warnings) { xmlNodePtr materialNode = root->children; wxString warning; while(materialNode) { warning = wxT(""); if(xmlStrcmp(materialNode->name,(const xmlChar*)"include") == 0) { std::string include_file; if(readXMLValue(materialNode, "file", include_file)) { FileName include_name; include_name.SetPath(filename.GetPath()); include_name.SetFullName(wxstr(include_file)); wxString suberror; bool success = loadMaterials(include_name, suberror, warnings); if(!success) warnings.push_back(wxT("Error while loading file \"") + wxstr(include_file) + wxT("\": ") + suberror); } } else if(xmlStrcmp(materialNode->name,(const xmlChar*)"metaitem") == 0) { item_db.loadMetaItem(materialNode); } else if(xmlStrcmp(materialNode->name,(const xmlChar*)"border") == 0) { brushes.unserializeBorder(materialNode, warnings); if(warning.size()) warnings.push_back(wxT("materials.xml: ") + warning); } else if(xmlStrcmp(materialNode->name,(const xmlChar*)"brush") == 0) { brushes.unserializeBrush(materialNode, warnings); if(warning.size()) warnings.push_back(wxT("materials.xml: ") + warning); } else if(xmlStrcmp(materialNode->name,(const xmlChar*)"tileset") == 0) { unserializeTileset(materialNode, warnings); } materialNode = materialNode->next; } return true; }
TGen::Engine::ResourceManager::ResourceManager(TGen::Engine::StandardLogs & logs, TGen::Engine::Filesystem & filesystem, TGen::Renderer & renderer, TGen::Engine::VariableRegister & variables) : logs(logs) , filesystem(filesystem) , renderer(renderer) , vertexCache(renderer, logs) , variables(variables) { logs.info["res+"] << "initializing resource manager..." << TGen::endl; std::vector<std::string> materialsToLoad; materialsToLoad.reserve(50); filesystem.enumerateFiles("/materials/", materialsToLoad, true); for (int i = 0; i < materialsToLoad.size(); ++i) { if (materialsToLoad[i].find(".svn") == std::string::npos) loadMaterials(materialsToLoad[i]); } }
// Create a model by deserializing it from Json Model::Model(const Json::Value& root, const std::string& directory, TextureCache &_textureCache) : meshes(0, NULL), skeleton(new Node()), textureCache(_textureCache), previousProgram(NULL), uploaded(false) { // Load animations loadAnimations(root); // Load materials loadMaterials(root, directory); // Load mesh data loadMeshes(root); // Load node data loadSkeleton(root); // Load parts loadParts(root); }
void loadMeshes() { if (m_meshesLoaded) { return; } if (!m_materialsLoaded) { loadMaterials(); } m_meshList.reset(); #define MESH_DESC(_name, _path) \ { \ m_meshList.add(cs::meshLoad(#_name, _path)); \ BX_CHECK((m_meshList.count()-1) == Assets::Meshes:: ##_name, "Initialization error."); \ } #include "assets_res.h" m_meshesLoaded = true; }
bool Materials::unserializeMaterials(const FileName& filename, pugi::xml_node node, wxString& error, wxArrayString& warnings) { wxString warning; pugi::xml_attribute attribute; for(pugi::xml_node childNode = node.first_child(); childNode; childNode = childNode.next_sibling()) { const std::string& childName = as_lower_str(childNode.name()); if(childName == "include") { if(!(attribute = childNode.attribute("file"))) { continue; } FileName includeName; includeName.SetPath(filename.GetPath()); includeName.SetFullName(wxString(attribute.as_string(), wxConvUTF8)); wxString subError; if(!loadMaterials(includeName, subError, warnings)) { warnings.push_back("Error while loading file \"" + includeName.GetFullName() + "\": " + subError); } } else if(childName == "metaitem") { g_items.loadMetaItem(childNode); } else if(childName == "border") { g_brushes.unserializeBorder(childNode, warnings); if(warning.size()) { warnings.push_back("materials.xml: " + warning); } } else if(childName == "brush") { g_brushes.unserializeBrush(childNode, warnings); if(warning.size()) { warnings.push_back("materials.xml: " + warning); } } else if(childName == "tileset") { unserializeTileset(childNode, warnings); } } return true; }
bool SceneLoader::loadScene() { sgxElement = doc.FirstChildElement( "sgx" ); globalsElement = sgxElement->FirstChildElement( "globals" ); viewElement = sgxElement->FirstChildElement( "view" ); illuminationElement = sgxElement->FirstChildElement("illumination"); texturesElement = sgxElement->FirstChildElement("textures"); objectsElement = sgxElement->FirstChildElement("objects"); materialsElement = sgxElement->FirstChildElement("materials"); Material * mat; Texture * tex; // Inicialização // Um exemplo de um conjunto de nós bem conhecidos e obrigatórios if(sgxElement == NULL) { cout << "Bloco sgx nao encontrado\n"; system("pause"); return false; } if(globalsElement != NULL) { if(!loadGlobals()) return false; } else { cout<<"Bloco globals nao encontrado\n"; system("pause"); return false; } if (viewElement != NULL) { if(!loadView()) return false; } else { cout << "Bloco view nao encontrado\n"; system("pause"); return false; } if(illuminationElement != NULL) { if(!loadIllumination()) return false; } else { cout<<"Bloco illumination nao econtrado\n"; system("pause"); return false; } if(texturesElement != NULL) { if(!loadTextures()) return false; } else { cout<<"Bloco textures nao econtrado\n"; system("pause"); return false; } if(materialsElement != NULL) { if(!loadMaterials()) return false; } else { cout<<"Bloco materials nao econtrado\n"; system("pause"); return false; } if(objectsElement!=NULL) { if(!loadObjects()) return false; if(!loadCompound()) return false; root_object=findObject(global.root); if(root_object==NULL) return false; if(root_object->mat_id=="null") mat=this->mat_base; else { mat=findMaterial(root_object->mat_id); if(mat==NULL) return false; } if(!aplicaMaterials(root_object, mat)) return false; if(root_object->tex_id=="null"||root_object->tex_id=="clear") tex=this->no_tex; else { tex=findTexture(root_object->tex_id); if(tex==NULL) return false; } if(!aplicaTextures(root_object, tex)) return false; } else { cout<<"Bloco objects nao econtrado\n"; system("pause"); return false; } return true; }
void MeshBase::loadDataFromObj( const std::string& filename ) { FILE* file = openObjFile(filename); int vertices_index = 0; int normals_index = 0; int colors_index = 0; int texture_coordinates_index = 0; int triangles_index = 0; float* vertices = m_vertex_data; float* normals = m_normal_data; unsigned char* colors = m_color_data; float* texture_coordinates = m_texture_coordinate_data; // 0 as a stride signals compact data int v_stride = m_vertex_stride == 0 ? 3 : m_vertex_stride; int n_stride = m_normal_stride == 0 ? 3 : m_normal_stride; int c_stride = m_color_stride == 0 ? 3 : m_color_stride; int t_stride = m_texture_coordinate_stride == 0 ? 2 : m_texture_coordinate_stride; bool is_loading_curr_group = false; std::string curr_group_name = default_group_name; std::string curr_group_base_name = default_group_name; MeshGroup* curr_group_data = 0; MeshGroupMap::const_iterator default_group_iter = m_mesh_groups.find(default_group_name); if( default_group_iter == m_mesh_groups.end() ) { is_loading_curr_group = false; curr_group_data = 0; } else { is_loading_curr_group = true; curr_group_data = &m_mesh_groups[default_group_name]; } std::string curr_material_name = default_material_name; int curr_material_number = 0; // Init. the current group triangle index to 0 for each group, so the current // triangle index of each can be tracked. std::map<std::string, int> groups_triangles_index; forEachGroup( GroupCurrentIndexInitFunctor(groups_triangles_index) ); // For improved speed, so that we don't need a lookup in groups_triangles_index // for every single face--only when the group changes. int* curr_group_triangles_index = &groups_triangles_index[default_group_name]; bool uses_vertices = ( m_num_vertices > 0 && vertices != 0 ); bool uses_normals = ( m_num_normals > 0 && normals != 0 ); bool uses_colors = ( m_num_colors > 0 && colors != 0 ); bool uses_texture_coordinates = ( m_num_texture_coordinates > 0 && texture_coordinates != 0 ); int v[3], n[3], t[3]; float f[3]; char buf[2048]; while(fscanf(file, "%s", buf) != EOF) { switch(buf[0]) { case '#': /* comment */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; case 'v': /* v, vn, vt */ switch(buf[1]) { case '\0': /* vertex */ if( !uses_colors ) { fscanf( file, "%f %f %f", &f[0], &f[1], &f[2] ); if( uses_vertices ) { for( int i = 0; i < 3; ++i ) { vertices[v_stride*vertices_index + i] = f[i]; } ++vertices_index; } } else { int c[3]; fscanf( file, "%f %f %f %d %d %d", &f[0], &f[1], &f[2], &c[0], &c[1], &c[2] ); if( uses_vertices ) { for( int i = 0; i < 3; ++i ) { vertices[v_stride*vertices_index + i] = f[i]; } ++vertices_index; } if( uses_colors ) { for( int i = 0; i < 3; ++i ) { colors[c_stride*colors_index + i] = static_cast<unsigned char>( c[i] ); ++colors_index; } } } break; case 'n': /* normal */ fscanf( file, "%f %f %f", &f[0], &f[1], &f[2] ); if( uses_normals ) { for( int i = 0; i < 3; ++i ) { normals[n_stride*normals_index + i] = f[i]; } ++normals_index; } break; case 't': /* texcoord */ fscanf( file, "%f %f", &f[0], &f[1] ); if( uses_texture_coordinates ) { for( int i = 0; i < 2; ++i ) { texture_coordinates[t_stride*texture_coordinates_index + i] = f[i]; } ++texture_coordinates_index; } break; } break; case 'u': /* "usemtl <name>" */ fgets(buf, sizeof(buf), file); sscanf(buf, "%s %s", buf, buf); curr_material_name = buf; curr_material_number = m_material_numbers_by_name.at(curr_material_name); curr_group_name = groupMaterialName( curr_group_base_name, curr_material_name ); // Set up a valid current group only if the new group hasn't been excluded from loading if( m_mesh_groups.find(curr_group_name) != m_mesh_groups.end() ) { is_loading_curr_group = true; curr_group_data = &m_mesh_groups[curr_group_name]; curr_group_triangles_index = &groups_triangles_index[curr_group_name]; curr_group_data->material_number = curr_material_number; } else { is_loading_curr_group = false; curr_group_data = 0; curr_group_triangles_index = 0; } break; case 'o': /* "o <object name>" */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; case 'g': /* "g <group name>" */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); sscanf(buf, "%s", buf); curr_group_base_name = buf; curr_group_name = groupMaterialName( curr_group_base_name, curr_material_name ); // Set up a valid current group only if the new group hasn't been excluded from loading if( m_mesh_groups.find( curr_group_name ) != m_mesh_groups.end() ) { is_loading_curr_group = true; curr_group_data = &m_mesh_groups[curr_group_name]; curr_group_triangles_index = &groups_triangles_index[curr_group_name]; curr_group_data->material_number = curr_material_number; } else { is_loading_curr_group = false; curr_group_data = 0; curr_group_triangles_index = 0; } break; case 'm': /* "mtllib <material library name>" */ fgets(buf, sizeof(buf), file); sscanf(buf, "%s %s", buf, buf); { std::string dir = directoryOfFilePath( filename ); std::stringstream ss_material_library_name; ss_material_library_name << dir << m_material_library_name; loadMaterials( ss_material_library_name.str() ); } break; case 'f': /* face */ #define NEWEST_INDEX(indices, vertex_offset) \ curr_group_data->indices[3*(*curr_group_triangles_index) + (vertex_offset)] #define PREVIOUS_INDEX(indices, vertex_offset) \ curr_group_data->indices[3*(*curr_group_triangles_index - 1) + (vertex_offset)] for (int i = 0; i < 3; ++i) { v[i] = n[i] = t[i] = 0; } fscanf(file, "%s", buf); /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */ if( strstr(buf, "//" )) { /* v//n */ sscanf(buf, "%d//%d", &v[0], &n[0]); fscanf(file, "%d//%d", &v[1], &n[1]); fscanf(file, "%d//%d", &v[2], &n[2]); // We still need to advance through the file, but don't store // what is parsed for groups we've been told not to load if( is_loading_curr_group ) { if( uses_vertices ) { for (int i = 0; i < 3; ++i) { NEWEST_INDEX(vertex_indices, i) = (v[i] >= 0) ? v[i] - 1 : (vertices_index + v[i]); } } if( uses_normals ) { for (int i = 0; i < 3; ++i) { NEWEST_INDEX(normal_indices, i) = n[i] - 1; } } if( uses_texture_coordinates ) { for (int i = 0; i < 3; ++i) { NEWEST_INDEX(texture_coordinate_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } ++(*curr_group_triangles_index); ++triangles_index; } // Load face as a triangle fan when there are more than three indices while(fscanf(file, "%d//%d", &v[0], &n[0]) > 0) { if( is_loading_curr_group ) { if( uses_vertices ) { NEWEST_INDEX(vertex_indices, 0) = PREVIOUS_INDEX(vertex_indices, 0); NEWEST_INDEX(vertex_indices, 1) = PREVIOUS_INDEX(vertex_indices, 2); NEWEST_INDEX(vertex_indices, 2) = (v[0] >= 0) ? v[0] - 1: (vertices_index + v[0]); } if( uses_normals ) { NEWEST_INDEX(normal_indices, 0) = PREVIOUS_INDEX(normal_indices, 0); NEWEST_INDEX(normal_indices, 1) = PREVIOUS_INDEX(normal_indices, 2); NEWEST_INDEX(normal_indices, 2) = n[0] - 1; } if( uses_texture_coordinates ) { for (int i = 0; i < 3; ++i) { NEWEST_INDEX(texture_coordinate_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } ++(*curr_group_triangles_index); ++triangles_index; } } } else if( sscanf(buf, "%d/%d/%d", &v[0], &t[0], &n[0] ) == 3) { /* v/t/n */ fscanf(file, "%d/%d/%d", &v[1], &t[1], &n[1]); fscanf(file, "%d/%d/%d", &v[2], &t[2], &n[2]); if( is_loading_curr_group ) { if( uses_vertices ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(vertex_indices, i) = (v[i] >= 0) ? v[i] - 1 : (vertices_index + v[i]); } } if( uses_normals ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(normal_indices, i) = n[i] - 1; } } if( uses_texture_coordinates ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(texture_coordinate_indices, i) = t[i] - 1; } } ++(*curr_group_triangles_index); ++triangles_index; } // Load face as a triangle fan when there are more than three indices while(fscanf(file, "%d/%d/%d", &v[0], &t[0], &n[0]) > 0) { if( is_loading_curr_group ) { if( uses_vertices ) { NEWEST_INDEX(vertex_indices, 0) = PREVIOUS_INDEX(vertex_indices, 0); NEWEST_INDEX(vertex_indices, 1) = PREVIOUS_INDEX(vertex_indices, 2); NEWEST_INDEX(vertex_indices, 2) = (v[0] >= 0) ? v[0] - 1 : (vertices_index + v[0]); } if( uses_normals ) { NEWEST_INDEX(normal_indices, 0) = PREVIOUS_INDEX(normal_indices, 0); NEWEST_INDEX(normal_indices, 1) = PREVIOUS_INDEX(normal_indices, 2); NEWEST_INDEX(normal_indices, 2) = n[0] - 1; } if( uses_texture_coordinates ) { NEWEST_INDEX(texture_coordinate_indices, 0) = PREVIOUS_INDEX(texture_coordinate_indices, 0); NEWEST_INDEX(texture_coordinate_indices, 1) = PREVIOUS_INDEX(texture_coordinate_indices, 2); NEWEST_INDEX(texture_coordinate_indices, 2) = t[0] - 1; } ++(*curr_group_triangles_index); ++triangles_index; } } } else if( sscanf(buf, "%d/%d", &v[0], &t[0] ) == 2) { /* v/t */ fscanf(file, "%d/%d", &v[1], &t[1]); fscanf(file, "%d/%d", &v[2], &t[2]); if( is_loading_curr_group ) { if( uses_vertices ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(vertex_indices, i) = (v[i] >= 0) ? v[i] - 1 : (vertices_index + v[i]); } } if( uses_normals ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(normal_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } if( uses_texture_coordinates ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(texture_coordinate_indices, i) = t[i] - 1; } } ++(*curr_group_triangles_index); ++triangles_index; } // Load face as triangle fan when more than three indices while(fscanf(file, "%d/%d", &v[0], &t[0]) > 0) { if( is_loading_curr_group ) { if( uses_vertices ) { NEWEST_INDEX(vertex_indices, 0) = PREVIOUS_INDEX(vertex_indices, 0); NEWEST_INDEX(vertex_indices, 1) = PREVIOUS_INDEX(vertex_indices, 2); NEWEST_INDEX(vertex_indices, 2) = (v[0] >= 0) ? v[0] - 1 : (vertices_index + v[0]); } if( uses_normals ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(normal_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } if( uses_texture_coordinates ) { NEWEST_INDEX(texture_coordinate_indices, 0) = PREVIOUS_INDEX(texture_coordinate_indices, 0); NEWEST_INDEX(texture_coordinate_indices, 1) = PREVIOUS_INDEX(texture_coordinate_indices, 2); NEWEST_INDEX(texture_coordinate_indices, 2) = t[0] - 1; } ++(*curr_group_triangles_index); ++triangles_index; } } } else { /* v */ sscanf(buf, "%d", &v[0]); fscanf(file, "%d", &v[1]); fscanf(file, "%d", &v[2]); if( is_loading_curr_group ) { if( uses_vertices ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(vertex_indices, i) = (v[i] >= 0) ? v[i] - 1 : (vertices_index + v[i]); } } if( uses_normals ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(normal_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } if( uses_texture_coordinates ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(texture_coordinate_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } ++(*curr_group_triangles_index); ++triangles_index; } // Load face with more than three indices as a triangle fan while(fscanf(file, "%d", &v[0]) > 0) { if( is_loading_curr_group ) { if( uses_vertices ) { NEWEST_INDEX(vertex_indices, 0) = PREVIOUS_INDEX(vertex_indices, 0); NEWEST_INDEX(vertex_indices, 1) = PREVIOUS_INDEX(vertex_indices, 2); NEWEST_INDEX(vertex_indices, 2) = (v[0] >= 0) ? v[0] - 1 : (vertices_index + v[0]); } if( uses_normals ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(normal_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } if( uses_texture_coordinates ) { for( int i = 0; i < 3; ++i ) { NEWEST_INDEX(texture_coordinate_indices, i) = MESH_ATTRIBUTE_NOT_PROVIDED; } } ++(*curr_group_triangles_index); triangles_index++; } } } #undef PREVIOUS_INDEX #undef NEWEST_INDEX break; default: /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; } } #if 0 /* announce the memory requirements */ printf(" Memory: %d bytes\n", vertices_index * 3*sizeof(float) + numnormals * 3*sizeof(float) * (numnormals ? 1 : 0) + numtexcoords * 3*sizeof(float) * (numtexcoords ? 1 : 0) + numtriangles * sizeof(GLMtriangle)); #endif // It happens that in a .obj, all the color indices are identical to the // vertex indices, so we simply copy them if( uses_colors ) { forEachGroup( VertexIndexToColorIndexCopyFunctor() ); } }
bool ObjFileLoader::load(const QString& file, std::vector<GLModel*>& modelList) { QFile f(file); if(!f.open(QIODevice::ReadOnly)) return false; QString path = "./"; int idx = file.lastIndexOf('/'); if(idx != -1) { path = file.left(idx+1); } QHash<QString, material> materials; QHash<QString, material>::iterator m_itr; QTextStream str(&f); GLModel *model = new GLModel(""); int vertexTotal = 0; int vertexModel = 0; int normalsTotal = 0; int normalsModel = 0; for(QString line = str.readLine(); !line.isNull(); line = str.readLine()) { if(line.startsWith('#')) continue; QStringList parts = line.split(' ', QString::SkipEmptyParts); if(parts.size() < 2) continue; int type = getObjType(parts[0]); if(type == -1) continue; switch(type) { case 5: // model { if(model) { model->createNormals(); modelList.push_back(model); } model = new GLModel(parts.back()); if(type == 5) { vertexTotal += vertexModel; vertexModel = 0; normalsTotal += normalsModel; normalsModel = 0; } continue; } case 8: // group { if(!model) model = new GLModel(parts.back()); continue; } case 6: // mtllib loadMaterials(path + parts.back(), materials); continue; } if(!model) continue; switch(type) { case 0: // vertex { double coords[4] = { 0.0, 0.0, 0.0, 1.0 }; for(int i = 1; i < parts.size() && i < 5; ++i) coords[i-1] = parts[i].toDouble(); model->addVertex(coords); ++vertexModel; break; } case 1: // face { polygonFace f; if(loadFace(parts, &f, vertexTotal, normalsTotal)) model->addFace(f); break; } case 2: // textures break; case 3: // normals { double coords[3] = { 0.0, 0.0, 0.0 }; for(int i = 1; i < parts.size() && i < 4; ++i) coords[i-1] = parts[i].toDouble(); model->addNormal(coords); ++normalsModel; break; } case 4: // smooth shading model->setSmoothShading(parts.back() != "off"); break; case 7: // usemtl { if(parts.back().isNull()) parts.back() = ""; m_itr = materials.find(parts.back()); if(m_itr == materials.end()) break; model->addMaterial(*m_itr); break; } } } if(model) { model->createNormals(); modelList.push_back(model); } return true; }
Mesh* loadModel(const char *filename, float size, int flags) { /* faces: only quads or triangles at the moment */ Mesh* mesh; Material *materials; FILE *f; char buf[120]; char namebuf[120]; char *path; float *vert; int *face; float *norm; int *normi; int *matIndex; float *vertex, *normal; int nNormals = 0; int nVertices = 0; int nFaces = 0; float *meshVerts; float *meshNorms; int *meshFacesize; int currentMat = 0; int matCount = 0; int *pMatCount = NULL; int iLine = 0; float t1[3], t2[3], t3[3]; int c, i, j, k, l, pos; int hasNorms = 0; int hasTexture = 0; int inv; if((f = fopen(filename, "r")) == 0) { fprintf(stderr, "could not open file\n"); return NULL; } vert = (float *) malloc(sizeof(float) * 3 * MAX_V); face = (int *) malloc(sizeof(int) * MODEL_FACESIZE * MAX_F); matIndex = (int *) malloc(sizeof(int) * MAX_F); normi = (int *) malloc(sizeof(int) * MODEL_FACESIZE * MAX_F); norm = (float *) malloc(sizeof(float) * 3 * MAX_N); while(fgets(buf, sizeof(buf), f)) { switch(buf[0]) { case 'm': /* material library? */ if(sscanf(buf, "mtllib %s ", namebuf) == 1) { /* load material library */ path = getFullPath(namebuf); if(path == NULL) { fprintf(stderr, "fatal: can't find mtllib '%s'\n", namebuf); exit(1); } matCount = loadMaterials(path, &materials); if(matCount <= 0) { fprintf(stderr, "fatal: no Materials loaded\n"); exit(1); } /* printf("loaded %d Materials\n", matCount); */ pMatCount = (int*) malloc(sizeof(int) * matCount); for(i = 0; i < matCount; i++) pMatCount[i] = 0; currentMat = 0; } else fprintf(stderr, "warning: ignored line %d\n", iLine); break; case 'u': case 'g': /* material name */ if(sscanf(buf, "usemtl %s ", namebuf) == 1) { for(i = 0; i < matCount; i++) { if(strcmp(namebuf, (materials + i)->name) == 0) { currentMat = i; break; /* break out of if */ } } } else currentMat = 0; break; case 'v': switch(buf[1]) { case ' ': /* vertex data */ if(nVertices >= MAX_V) { FAIL("vertex limit exceeded\n") ; } c = sscanf(buf, "v %f %f %f ", vert + nVertices * 3, vert + nVertices * 3 + 1, vert + nVertices * 3 + 2); for(i = c; i < 3; i++) { printf("this should not happen\n"); *(vert + nVertices * 3 + i) = 0; } nVertices++; break; case 'n': /* vertex normal */ hasNorms = 1; if(nVertices >= MAX_N) { FAIL("normals limit exceeded\n") ; } c = sscanf(buf, "vn %f %f %f ", norm + nNormals * 3, norm + nNormals * 3 + 1, norm + nNormals * 3 + 2); for(i = c; i < 3; i++) { printf("this should not happen\n"); *(norm + nNormals * 3 + i) = 0; break; } nNormals++; break; case 't': /* texture coordinate - ignored */ hasTexture = 1; break; } break; case 'f': if(nFaces * MODEL_FACESIZE >= MAX_F) { FAIL("face limit exceeded\n") ; } /* mark material */ *(matIndex + nFaces) = currentMat; if(matCount > 0 && pMatCount != NULL) pMatCount[currentMat]++; if(hasNorms) { int dummy1, dummy2, dummy3, dummy4; if (hasTexture) { c = sscanf(buf, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d ", face + nFaces * MODEL_FACESIZE, &dummy1, normi + nFaces * MODEL_FACESIZE, face + nFaces * MODEL_FACESIZE + 1, &dummy2, normi + nFaces * MODEL_FACESIZE + 1, face + nFaces * MODEL_FACESIZE + 2, &dummy3, normi + nFaces * MODEL_FACESIZE + 2, face + nFaces * MODEL_FACESIZE + 3, & dummy4, normi + nFaces * MODEL_FACESIZE + 3); } else { c = sscanf(buf, "f %d//%d %d//%d %d//%d %d//%d ", face + nFaces * MODEL_FACESIZE, normi + nFaces * MODEL_FACESIZE, face + nFaces * MODEL_FACESIZE + 1, normi + nFaces * MODEL_FACESIZE + 1, face + nFaces * MODEL_FACESIZE + 2, normi + nFaces * MODEL_FACESIZE + 2, face + nFaces * MODEL_FACESIZE + 3, normi + nFaces * MODEL_FACESIZE + 3); } for(i = c / 2; i < MODEL_FACESIZE; i++) { *(face + nFaces * MODEL_FACESIZE + i) = -1; *(normi + nFaces * MODEL_FACESIZE + i) = -1; } nFaces++; } else { /* TODO: add if(hasTexture) */ c = sscanf(buf, "f %d %d %d %d ", face + nFaces * MODEL_FACESIZE, face + nFaces * MODEL_FACESIZE + 1, face + nFaces * MODEL_FACESIZE + 2, face + nFaces * MODEL_FACESIZE + 3); for(i = c; i < MODEL_FACESIZE; i++) *(face + nFaces * MODEL_FACESIZE + i) = -1; nFaces++; } break; } iLine++; } if(hasNorms == 0) { /* create Normals */ for(i = 0; i < nFaces; i++) { t1[0] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 0) - 1) + 0); t1[1] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 0) - 1) + 1); t1[2] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 0) - 1) + 2); t2[0] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 1) - 1) + 0); t2[1] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 1) - 1) + 1); t2[2] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 1) - 1) + 2); t3[0] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 2) - 1) + 0); t3[1] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 2) - 1) + 1); t3[2] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 2) - 1) + 2); /* printf("face %d:\n", i); printf("v1: %f %f %f\n", t1[0], t1[1], t1[2]); printf("v2: %f %f %f\n", t2[0], t2[1], t2[1]); printf("v3: %f %f %f\n", t3[0], t3[1], t3[1]); */ t1[0] -= t3[0]; t1[1] -= t3[1]; t1[2] -= t3[2]; t2[0] -= t3[0]; t2[1] -= t3[1]; t2[2] -= t3[2]; normcrossprod(t1, t2, t3); /* printf("normal: %f %f %f\n\n", t3[0], t3[1], t3[2]); */ /* t3 now contains the face normal */ for(j = 0; j < MODEL_FACESIZE; j++) *(normi + i * MODEL_FACESIZE + j) = nNormals + 1; *(norm + nNormals * 3 + 0) = t3[0]; *(norm + nNormals * 3 + 1) = t3[1]; *(norm + nNormals * 3 + 2) = t3[2]; nNormals++; } /* printf("generated %d normals\n", nNormals); */ } if(matCount == 0) { /* create Default material */ float spec[] = { 0.77, 0.77, 0.77, 1.0 }; float dif[] = { 0.4, 0.4, 0.4, 1}; float amb[] = { 0.25, 0.25, 0.25, 1}; materials = (Material*) malloc(sizeof(Material)); materials->name = (char*) malloc(strlen("default") + 1); sprintf(materials->name, "default"); memcpy(materials->ambient, amb, 3 * sizeof(float)); memcpy(materials->diffuse, dif, 3 * sizeof(float)); memcpy(materials->specular, spec, 3 * sizeof(float)); matCount = 1; pMatCount = (int*) malloc(sizeof(int)); pMatCount[0] = nFaces; } /* everything is parsed, now allocate memory and */ /* rescale and get bbox */ /* copy data to Mesh structure */ /* new: sort into sub meshes with by materials */ if(flags & MODEL_INVERT_NORMALS) { /* invert normals */ /* printf("inverting normals...really!\n"); */ inv = -1; } else inv = 1; mesh = (Mesh*) malloc(sizeof(Mesh)); /* rescale */ rescaleVertices(vert, size, nVertices, mesh->bbox); mesh->nFaces = nFaces; mesh->nMaterials = matCount; mesh->materials = materials; mesh->meshparts = (MeshPart*) malloc(matCount * sizeof(MeshPart)); for(i = 0; i < matCount; i++) { meshVerts = (float*) malloc(pMatCount[i] * 3 * MODEL_FACESIZE * sizeof(float)); meshNorms = (float*) malloc(pMatCount[i] * 3 * MODEL_FACESIZE * sizeof(float)); meshFacesize = (int*) malloc(pMatCount[i] * sizeof(int)); /* printf("Material %d: %d faces\n", i, pMatCount[i]); */ (mesh->meshparts + i)->nFaces = pMatCount[i]; (mesh->meshparts + i)->vertices = meshVerts; (mesh->meshparts + i)->normals = meshNorms; (mesh->meshparts + i)->facesizes = meshFacesize; pos = 0; for(j = 0; j < nFaces; j++) { /* foreach face */ if(matIndex[j] == i) { *(meshFacesize + pos) = 0; /* printf("face %d\n", j); */ for(k = 0; k < MODEL_FACESIZE; k++) { /* foreach vertex of face */ if(*(face + j * MODEL_FACESIZE + k) != -1) { *(meshFacesize + pos) += 1; /* adjust facesize... */ /* copy face and normal data to meshVerts, meshNorms */ vertex = vert + 3 * ( *(face + j * MODEL_FACESIZE + k) - 1); normal = norm + 3 * ( *(normi + j * MODEL_FACESIZE + k) - 1); if(flags & MODEL_NORMALIZE) normalize(normal); for(l = 0; l < 3; l++) { /* printf("%f ", vertex[l]); */ *(meshVerts + 3 * (pos * MODEL_FACESIZE + k) + l) = *(vertex + l); *(meshNorms + 3 * (pos * MODEL_FACESIZE + k) + l) = inv * *(normal + l); } /* printf("\n"); */ } } pos++; if(pos > pMatCount[i]) { fprintf(stderr, "fatal: more faces than accounted for\n"); exit(1); } } } } free(vert); free(face); free(norm); free(normi); free(pMatCount); free(matIndex); fclose (f); /* printf("loaded model: %d vertices, %d normals, %d faces, %d materials\n", nVertices, nNormals, nFaces, matCount); */ return mesh; }
void initGame(void) { lcdMainOnTop(); int oldv=getMemFree(); NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree()); NOGBA("initializing..."); videoSetMode(MODE_5_3D | DISPLAY_BG3_ACTIVE); videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE); glInit(); vramSetPrimaryBanks(VRAM_A_TEXTURE,VRAM_B_TEXTURE,VRAM_C_LCD,VRAM_D_MAIN_BG_0x06000000); vramSetBankH(VRAM_H_SUB_BG); vramSetBankI(VRAM_I_SUB_BG_0x06208000); glEnable(GL_TEXTURE_2D); // glEnable(GL_ANTIALIAS); glDisable(GL_ANTIALIAS); glEnable(GL_BLEND); glEnable(GL_OUTLINE); glSetOutlineColor(0,RGB15(0,0,0)); //TEMP? glSetOutlineColor(1,RGB15(0,0,0)); //TEMP? glSetOutlineColor(7,RGB15(31,0,0)); //TEMP? glSetToonTableRange(0, 15, RGB15(8,8,8)); //TEMP? glSetToonTableRange(16, 31, RGB15(24,24,24)); //TEMP? glClearColor(31,31,0,31); glClearPolyID(63); glClearDepth(0x7FFF); glViewport(0,0,255,191); // initVramBanks(1); initVramBanks(2); initTextures(); initSound(); initCamera(NULL); initPlayer(NULL); initLights(); initParticles(); initMaterials(); loadMaterialSlices("slices.ini"); loadMaterials("materials.ini"); loadControlConfiguration("config.ini"); initElevators(); initWallDoors(); initTurrets(); initBigButtons(); initTimedButtons(); initEnergyBalls(); initPlatforms(); initCubes(); initEmancipation(); initDoors(); initSludge(); initPause(); initText(); NOGBA("lalala"); getPlayer()->currentRoom=&gameRoom; currentBuffer=false; getVramStatus(); fadeIn(); mainBG=bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0); bgSetPriority(mainBG, 0); REG_BG0CNT=BG_PRIORITY(3); #ifdef DEBUG_GAME consoleInit(&bottomScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 16, 0, false, true); consoleSelect(&bottomScreen); #endif // glSetToonTableRange(0, 14, RGB15(16,16,16)); // glSetToonTableRange(15, 31, RGB15(26,26,26)); initPortals(); //PHYSICS initPI9(); strcpy(&mapFilePath[strlen(mapFilePath)-3], "map"); newReadMap(mapFilePath, NULL, 255); transferRectangles(&gameRoom); makeGrid(); generateRoomGrid(&gameRoom); gameRoom.displayList=generateRoomDisplayList(&gameRoom, vect(0,0,0), vect(0,0,0), false); getVramStatus(); startPI(); NOGBA("START mem free : %dko (%do)",getMemFree()/1024,getMemFree()); NOGBA("vs mem free : %dko (%do)",oldv/1024,oldv); levelInfoCounter=60; }
void GLAssimpMeshBinding::load(const aiScene *scene, const aiMesh *mesh) { // only process if we haven't already loaded this - otherwise is just GL reload if (!this->mesh) { Property *prop = btGetContext()->appProperties->get("debug_assimp"); if (prop) { debugAssimp = prop->getBoolValue(); } this->mesh = mesh; hasBones = (mesh->mNumBones > 0); if (hasBones) { vertSkinnedAtts = new GLAssimpSkinnedMeshVertex[mesh->mNumVertices]; } else { vertBasicAtts = new GLAssimpMeshVertex[mesh->mNumVertices]; } if (hasBones) { for (U32 i = 0; i < mesh->mNumVertices; i++) { aiVector3D vert = mesh->mVertices[i]; aiVector3D normal = mesh->mNormals[i]; aiVector3D uv = mesh->mTextureCoords[0][i]; vertSkinnedAtts[i].position = Vector3f(vert.x, vert.y, vert.z); vertSkinnedAtts[i].normal = Vector3f(normal.x, normal.y, normal.z); vertSkinnedAtts[i].uv = Vector2f(uv.x, uv.y); vertSkinnedAtts[i].bones = Vector4b(0, 0, 0, 0); vertSkinnedAtts[i].weights = Vector4f(0, 0, 0, 0); } U32 *weightCounts = new U32[mesh->mNumVertices]; memset(weightCounts, 0, mesh->mNumVertices * 4); BOOL32 discardedWeights = FALSE; for (U8 i = 0; i < (U8)mesh->mNumBones; i++) { aiBone *bone = mesh->mBones[i]; for (U32 j = 0; j < bone->mNumWeights; j++) { U32 vertIdx = bone->mWeights[j].mVertexId; F32 weight = bone->mWeights[j].mWeight; U32 weightNum = weightCounts[vertIdx]; if (weightNum < 4) { vertSkinnedAtts[vertIdx].bones[weightNum] = i; vertSkinnedAtts[vertIdx].weights[weightNum] = weight; weightCounts[vertIdx]++; } else { discardedWeights = TRUE; } } } delete [] weightCounts; if (discardedWeights) { logmsg("AssimpBind Warning: Too many bone weights - discarding!"); } } else { for (U32 i = 0; i < mesh->mNumVertices; i++) { aiVector3D vert = mesh->mVertices[i]; aiVector3D normal = mesh->mNormals[i]; aiVector3D uv = mesh->mTextureCoords[0][i]; vertBasicAtts[i].position = Vector3f(vert.x, vert.y, vert.z); vertBasicAtts[i].normal = Vector3f(normal.x, normal.y, normal.z); vertBasicAtts[i].uv = Vector2f(uv.x, uv.y); } } loadMaterials(scene->mMaterials[mesh->mMaterialIndex]); } U16 *faceIndices = new U16[this->mesh->mNumFaces * 3]; for (U32 i = 0; i < this->mesh->mNumFaces; i++) { aiFace face = this->mesh->mFaces[i]; faceIndices[i*3] = face.mIndices[0]; faceIndices[i*3+1] = face.mIndices[1]; faceIndices[i*3+2] = face.mIndices[2]; } loadGeometry(this->mesh, faceIndices); delete [] faceIndices; }