Exemple #1
0
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);
	}
Exemple #5
0
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")
Exemple #7
0
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();
}
Exemple #8
0
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;
}
Exemple #9
0
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);
}
Exemple #10
0
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;
}
Exemple #11
0
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]);
	}
}
Exemple #12
0
// 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);
}
Exemple #13
0
    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;
    }
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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() );
  }
}
Exemple #17
0
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;
}
Exemple #18
0
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;
}
Exemple #19
0
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;
	}