/** * @brief * Saves the material */ bool PLSceneMaterial::Save(const String &sApplicationDrive, const String &sApplicationDir) { // Create XML document XmlDocument cDocument; // Add declaration XmlDeclaration *pDeclaration = new XmlDeclaration("1.0", "ISO-8859-1", ""); cDocument.LinkEndChild(*pDeclaration); // Add material XmlElement *pMaterialElement = new XmlElement("Material"); pMaterialElement->SetAttribute("Version", "1"); // Save the parameters SaveParameters(*pMaterialElement); // Link material element cDocument.LinkEndChild(*pMaterialElement); // Get the absolute material filename const String sFilename = sApplicationDrive + sApplicationDir + PLTools::GetResourceFilename(PLTools::ResourceMaterial, m_sName); { // Before we safe, we need to ensure that the target directory is there, else 'Save()' will fail! Url cUrl = sFilename; Directory cDirectory(cUrl.CutFilename()); cDirectory.CreateRecursive(); } // Save settings cDocument.Save(sFilename); // Done return true; }
/** * @brief * Loads a resource which type has to be evaluated internally */ bool Application::LoadResource(const String &sFilename, const String &sType) { bool bResult = false; // Error by default // Clear the scene, after calling this method the scene is empty ClearScene(); // Destroy the currently used script DestroyScript(); // Backup the filename of the current resource m_sResourceFilename = sFilename; // Is there anything to load in? if (sFilename.GetLength()) { { // Make the directory of the scene to load in to the current directory // Ok, the next thing is tricky, and every solution will end up in being a hack due to lack of information. // Within materials, meshes etc. there are usually relative paths provided, no absolute (not just true for PixelLight file formats). // Further, those paths are usually relative to a project root resulting e.g. within a default directory layout like // - Root // - Data // - Meshes // - Materials // For "normal" projects this is no issue because everything is usually relative to the root project directory... // ... but this viewer must be able to pick out e.g. a mesh out of nowhere and must still be able to locate the required // other resources like materials. So, in here, we can only work with heuristics... this can and will of course go from // time to time horribly wrong... // First try: Find the first "Data" occurrence with the given filename and hope that it's the project root directory // Get filename as clean URL Url cUrl = Url(sFilename); cUrl.Collapse(); // Get the first part of the path, and then look for "Data" uint32 nPathPos = 0; String sPart = cUrl.GetFirstPath(nPathPos); while (sPart != "Data" && sPart.GetLength()) sPart = cUrl.GetNextPath(nPathPos); if (sPart == "Data") { // Set the base directory of the application SetBaseDirectory(cUrl.GetRoot() + cUrl.GetPath().GetSubstring(0, nPathPos - 5)); // -5 = Remove "Data/" } else { // Second try: Cut of "/Data/Scenes/" and hope that it's the project root directory. // If it's not there, take the directory the given resource is in. // Validate path const String sDirectory = cUrl.CutFilename(); // Search for "/Data/Scenes/" and get the prefix of that, in case it's not there just use directly the scene directory const int nIndex = sDirectory.IndexOf("/Data/Scenes/"); // Set the base directory of the application SetBaseDirectory("file://" + ((nIndex >= 0) ? sDirectory.GetSubstring(0, nIndex) : sDirectory) + '/'); } }