/** * @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 * Saves the parsed information to the given file */ void PLPluginInfo::Save(File &cFile) const { XmlDocument cDocument; AppendInformation(cDocument); cDocument.Save(cFile); }
/** * @brief * Saves the parsed information to the given file */ void PLPluginInfo::Save(const String &sFilename) const { XmlDocument cDocument; AppendInformation(cDocument); cDocument.Save(sFilename); }
/** * @brief * Constructor */ PLSceneTexture::PLSceneTexture(PLScene &cScene, const String &sName, bool bNormalMap_xGxR) : m_pScene(&cScene), m_sName(sName), m_nReferenceCount(0) { // Cut of the path of the map name - if there's one String sAbsBitmapFilename = m_sName; // Get the texture name m_sName = sName; // Check options if (g_SEOptions.bCopyTextures) { // Can we use the given absolute filename? HANDLE hFile = CreateFileW(sAbsBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { // Get the current path of the loaded 3ds Max scene String sCurFilePath = Url(GetCOREInterface()->GetCurFilePath().data()).CutFilename(); if (sCurFilePath.GetLength()) { // Compose absolute filename by just concatenating the two filenames (for relative filenames) String sBitmapFilename = sCurFilePath + sAbsBitmapFilename; hFile = CreateFileW(sBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { // Get the filename without any path information String sFilenameOnly = Url(sName).GetFilename().GetASCII(); // Compose absolute filename if (sFilenameOnly.GetLength()) { char nLastCharacter = sCurFilePath[sCurFilePath.GetLength()-1]; if (nLastCharacter == '\\' || nLastCharacter == '/') sBitmapFilename = sCurFilePath + sFilenameOnly; else sBitmapFilename = sCurFilePath + "\\" + sFilenameOnly; hFile = CreateFileW(sBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { // Check map directories int nMapDirCount = TheManager->GetMapDirCount(); for (int nMapDir=0; nMapDir<nMapDirCount; nMapDir++) { const String sMapDir = TheManager->GetMapDir(nMapDir); const uint32 nLength = sMapDir.GetLength(); if (nLength) { nLastCharacter = sMapDir[nLength-1]; if (nLastCharacter == '\\' || nLastCharacter == '/') sBitmapFilename = sMapDir + sFilenameOnly; else sBitmapFilename = sMapDir + '\\' + sFilenameOnly; hFile = CreateFileW(sBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile != INVALID_HANDLE_VALUE) break; else sAbsBitmapFilename = sBitmapFilename; } } } else { sAbsBitmapFilename = sBitmapFilename; } } } else { sAbsBitmapFilename = sBitmapFilename; } } } if (hFile != INVALID_HANDLE_VALUE) { // Get source file time and close it FILETIME sSourceCreationTime; FILETIME sSourceLastAccessTime; FILETIME sSourceLastWriteTime; GetFileTime(hFile, &sSourceCreationTime, &sSourceLastAccessTime, &sSourceLastWriteTime); CloseHandle(hFile); // Cut of the filename String sFilename = Url(g_SEOptions.sFilename).CutFilename(); // Construct the absolute target filename uint32 nLength = sFilename.GetLength(); if (nLength) { sFilename = sFilename + m_sName; // Is there already such a file? If yes, check the file times... hFile = CreateFileW(sFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile != INVALID_HANDLE_VALUE) { // Get target file time and close it FILETIME sTargetCreationTime; FILETIME sTargetLastAccessTime; FILETIME sTargetLastWriteTime; GetFileTime(hFile, &sTargetCreationTime, &sTargetLastAccessTime, &sTargetLastWriteTime); CloseHandle(hFile); // Compare file time long nResult = CompareFileTime(&sTargetLastWriteTime, &sSourceLastWriteTime); if (nResult >= 0) return; // Nothing to do :) } { // Before we copy, we need to ensure that the target directory is there, else 'CopyFile()' will fail! Directory cDirectory(Url(sFilename).CutFilename()); cDirectory.CreateRecursive(); } // Copy the texture (bitmap) CopyFileW(sAbsBitmapFilename.GetUnicode(), sFilename.GetUnicode(), false); // If there's a 'plt'-file for the texture, copy it, too int nIndex = sFilename.LastIndexOf("."); if (nIndex >= 0) { sFilename.Delete(nIndex); sFilename += ".plt"; nIndex = sAbsBitmapFilename.LastIndexOf("."); if (nIndex >= 0) { sAbsBitmapFilename.Delete(nIndex); sAbsBitmapFilename += ".plt"; if (!CopyFileW(sAbsBitmapFilename.GetUnicode(), sFilename.GetUnicode(), false)) { // Failed to copy the 'plt'-file... if (bNormalMap_xGxR) { // Create an automatic 'plt'-file... // Create XML document XmlDocument cDocument; // Add declaration XmlDeclaration *pDeclaration = new XmlDeclaration("1.0", "ISO-8859-1", ""); cDocument.LinkEndChild(*pDeclaration); // Add texture XmlElement *pTextureElement = new XmlElement("Texture"); // Setup attribute pTextureElement->SetAttribute("Version", "1"); // Add general XmlElement *pGeneralElement = new XmlElement("Node"); pGeneralElement->SetAttribute("Compression", "DXT5_xGxR"); // Link general element pTextureElement->LinkEndChild(*pGeneralElement); // Link material element cDocument.LinkEndChild(*pTextureElement); // Save settings if (cDocument.Save(sFilename)) g_pLog->LogFLine(PLLog::Hint, "Created '%s'", sFilename.GetASCII()); else g_pLog->LogFLine(PLLog::Error, "Can't create '%s'!", sFilename.GetASCII()); } } } } } } else { g_pLog->LogFLine(PLLog::Error, "Can't find texture (bitmap) '%s'!", m_sName.GetASCII()); } } }
//[-------------------------------------------------------] //[ Private virtual PLSceneNode functions ] //[-------------------------------------------------------] void PLSceneSpline::WriteToFile(XmlElement &cSceneElement, const String &sApplicationDrive, const String &sApplicationDir) { // Do NOT save it as scene node, it's just a 'resource' // Get path filename const String sFilename = sApplicationDrive + sApplicationDir + PLTools::GetResourceFilename(PLTools::ResourcePath, GetName() + ".path"); // Get the IGame spline object of the given IGame node IGameObject *pIGameObject = GetIGameNode()->GetIGameObject(); if (pIGameObject) { // Check the type of the IGame object if (pIGameObject->GetIGameType() == IGameObject::IGAME_SPLINE && pIGameObject->InitializeData()) { IGameSpline &cIGameSpline = *static_cast<IGameSpline*>(pIGameObject); if (cIGameSpline.GetNumberOfSplines () > 0) { // We only support spline 0 IGameSpline3D *pIGameSpline3D = cIGameSpline.GetIGameSpline3D(0); if (pIGameSpline3D) { // Get the local transform matrix GMatrix mTransform = cIGameSpline.GetIGameObjectTM(); // Get the 3ds Max shape object ShapeObject *pMaxShapeObject = static_cast<ShapeObject*>(pIGameObject->GetMaxObject()->ConvertToType(TIME_PosInfinity, Class_ID(GENERIC_SHAPE_CLASS_ID, 0))); if (pMaxShapeObject != nullptr && pMaxShapeObject->NumberOfCurves() == cIGameSpline.GetNumberOfSplines()) { // Create XML document XmlDocument cDocument; // Add declaration XmlDeclaration *pDeclaration = new XmlDeclaration("1.0", "ISO-8859-1", ""); cDocument.LinkEndChild(*pDeclaration); // Add path XmlElement *pPathElement = new XmlElement("Path"); // Setup attributes pPathElement->SetAttribute("Version", "1"); pPathElement->SetAttribute("Closed", String::Format("%d", pMaxShapeObject->CurveClosed(0, 0))); // Add all nodes for (int nKnot=0; nKnot<pIGameSpline3D->GetIGameKnotCount(); nKnot++) { IGameKnot *pIGameKnot = pIGameSpline3D->GetIGameKnot(nKnot); if (pIGameKnot) { // Get knot point in object space (although it is not documented it looks like object space...) Point3 cPoint = pIGameKnot->GetKnotPoint(); // We really need to flip the coordinates to OpenGL style, IGame is not doing this automatically... cPoint = PLTools::Convert3dsMaxVectorToOpenGLVector(cPoint); // Transform to world space cPoint = cPoint*mTransform; // If there's a parent container, make the position of this scene node relative to it PLSceneContainer *pContainer = GetContainer(); if (pContainer) cPoint -= pContainer->GetWorldSpaceCenter(); // Add node XmlElement *pNodeElement = new XmlElement("Node"); pNodeElement->SetAttribute("Name", String::Format("%d", nKnot)); pNodeElement->SetAttribute("Position", String::Format("%f %f %f", cPoint.x, cPoint.y, cPoint.z)); // Link general element pPathElement->LinkEndChild(*pNodeElement); } } // Link material element cDocument.LinkEndChild(*pPathElement); // Save settings if (cDocument.Save(sFilename)) g_pLog->LogFLine(PLLog::Hint, "Created '%s'", sFilename.GetASCII()); else g_pLog->LogFLine(PLLog::Error, "Can't create '%s'!", sFilename.GetASCII()); } } } } else { g_pLog->LogFLine(PLLog::Error, "%s: IGame object is no known spline object!", GetIGameNode()->GetName()); } // Release the IGame object GetIGameNode()->ReleaseIGameObject(); } else { g_pLog->LogFLine(PLLog::Error, "%s: IGame node has no IGame object!", GetIGameNode()->GetName()); } }