82f6d249eb
Several image preset files had a full list of file masks for only one platform. I made sure that the same list was applied to every platform including the default preset. Removed the "Swizzle" command from Displacement.preset. Swizzle "aaa1" is wrong since this preset expects a single channel image. Added "_col" to Albedo.preset as an abbreviation for "_color". Added "_rough" to Roughness.preset as it's a common abbreviation. Added "_rgbmask" filter to LayerMask.preset to correspond to the "_mask" filter in Grayscale.preset. Added a warning when an image can't be processed according to the assigned preset due to dimension issues. Otherwise it's difficult to figure out why it's using the ReferenceImage preset instead of what was expected. Resized the "bark" textures to make them compatible with the image presets. Removed the "bark1disp2.jgp" image and just applied the changes to the original bark1disp.jpg". It's just blurred a bit to remove excessive noise. Renamed all the "bark" textures to include an underscore "_" after "bark1" to get the image pipeline to properly recognize the file masks. Testing: AtomSampleViewer automation. All assets in AtomTest build. Opened several levels in AtomTest.
567 lines
22 KiB
C++
567 lines
22 KiB
C++
/*
|
|
* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution(the "License").All use of this software is governed by the License,
|
|
*or, if provided, by the license below or the license accompanying this file.Do not
|
|
* remove or modify any license notices.This file is distributed on an "AS IS" BASIS,
|
|
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
|
|
#include "ImageProcessing_precompiled.h"
|
|
|
|
#include "BuilderSettingManager.h"
|
|
#include <QDirIterator>
|
|
#include <QFile>
|
|
#include <QFileInfo>
|
|
#include <QString>
|
|
|
|
#include <Atom/ImageProcessing/PixelFormats.h>
|
|
#include <BuilderSettings/CubemapSettings.h>
|
|
#include <BuilderSettings/TextureSettings.h>
|
|
#include <Converters/Cubemap.h>
|
|
#include <Processing/PixelFormatInfo.h>
|
|
#include <Processing/ImageToProcess.h>
|
|
#include <ImageLoader/ImageLoaders.h>
|
|
#include <ImageProcessing_Traits_Platform.h>
|
|
|
|
#include <AssetBuilderSDK/AssetBuilderSDK.h>
|
|
|
|
#include <AzCore/IO/Path/Path.h>
|
|
#include <AzCore/Math/Sha1.h>
|
|
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <AzCore/Serialization/ObjectStream.h>
|
|
#include <AzCore/Serialization/Utils.h>
|
|
#include <AzCore/std/smart_ptr/make_shared.h>
|
|
#include <AzCore/std/string/string.h>
|
|
#include <AzFramework/IO/LocalFileIO.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
#include <AzFramework/Application/Application.h>
|
|
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
|
|
|
#include <AtomCore/Serialization/Json/JsonUtils.h>
|
|
|
|
namespace ImageProcessingAtom
|
|
{
|
|
const char* BuilderSettingManager::s_defaultConfigRelativeFolder = "Gems/Atom/Asset/ImageProcessingAtom/Config/";
|
|
const char* BuilderSettingManager::s_projectConfigRelativeFolder = "Config/AtomImageBuilder/";
|
|
const char* BuilderSettingManager::s_builderSettingFileName = "ImageBuilder.settings";
|
|
const char* BuilderSettingManager::s_presetFileExtension = ".preset";
|
|
|
|
const char FileMaskDelimiter = '_';
|
|
|
|
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
|
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3) \
|
|
namespace ImageProcess##PrivateName \
|
|
{ \
|
|
bool DoesSupport(AZStd::string); \
|
|
}
|
|
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
|
|
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
|
|
#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
|
|
|
|
const char* BuilderSettingManager::s_environmentVariableName = "ImageBuilderSettingManager_Atom";
|
|
AZ::EnvironmentVariable<BuilderSettingManager*> BuilderSettingManager::s_globalInstance = nullptr;
|
|
AZStd::mutex BuilderSettingManager::s_instanceMutex;
|
|
const PlatformName BuilderSettingManager::s_defaultPlatform = AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM;
|
|
|
|
void BuilderSettingManager::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<BuilderSettingManager>()
|
|
->Version(1)
|
|
->Field("AnalysisFingerprint", &BuilderSettingManager::m_analysisFingerprint)
|
|
->Field("BuildSettings", &BuilderSettingManager::m_builderSettings)
|
|
->Field("DefaultPresetsByFileMask", &BuilderSettingManager::m_defaultPresetByFileMask)
|
|
->Field("DefaultPreset", &BuilderSettingManager::m_defaultPreset)
|
|
->Field("DefaultPresetAlpha", &BuilderSettingManager::m_defaultPresetAlpha)
|
|
->Field("DefaultPresetNonePOT", &BuilderSettingManager::m_defaultPresetNonePOT);
|
|
}
|
|
}
|
|
|
|
BuilderSettingManager* BuilderSettingManager::Instance()
|
|
{
|
|
AZStd::lock_guard<AZStd::mutex> lock(s_instanceMutex);
|
|
|
|
if (!s_globalInstance)
|
|
{
|
|
s_globalInstance = AZ::Environment::FindVariable<BuilderSettingManager*>(s_environmentVariableName);
|
|
}
|
|
AZ_Assert(s_globalInstance, "BuilderSettingManager not created!");
|
|
|
|
return s_globalInstance.Get();
|
|
}
|
|
|
|
void BuilderSettingManager::CreateInstance()
|
|
{
|
|
AZStd::lock_guard<AZStd::mutex> lock(s_instanceMutex);
|
|
|
|
if (s_globalInstance)
|
|
{
|
|
AZ_Assert(false, "BuilderSettingManager already created!");
|
|
return;
|
|
}
|
|
|
|
if (!s_globalInstance)
|
|
{
|
|
s_globalInstance = AZ::Environment::CreateVariable<BuilderSettingManager*>(s_environmentVariableName);
|
|
}
|
|
if (!s_globalInstance.Get())
|
|
{
|
|
s_globalInstance.Set(aznew BuilderSettingManager());
|
|
}
|
|
}
|
|
|
|
void BuilderSettingManager::DestroyInstance()
|
|
{
|
|
AZStd::lock_guard<AZStd::mutex> lock(s_instanceMutex);
|
|
AZ_Assert(s_globalInstance, "Invalid call to DestroyInstance - no instance exists.");
|
|
AZ_Assert(s_globalInstance.Get(), "You can only call DestroyInstance if you have called CreateInstance.");
|
|
|
|
delete s_globalInstance.Get();
|
|
s_globalInstance.Reset();
|
|
}
|
|
|
|
const PresetSettings* BuilderSettingManager::GetPreset(const PresetName& presetName, const PlatformName& platform, AZStd::string_view* settingsFilePathOut)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
auto itr = m_presets.find(presetName);
|
|
if (itr != m_presets.end())
|
|
{
|
|
if (settingsFilePathOut)
|
|
{
|
|
*settingsFilePathOut = itr->second.m_presetFilePath;
|
|
}
|
|
return itr->second.m_multiPreset.GetPreset(platform);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const PresetSettings* BuilderSettingManager::GetPreset(const AZ::Uuid presetId, const PlatformName& platform, AZStd::string_view* settingsFilePathOut)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
|
|
for (const auto& namePreset : m_presets)
|
|
{
|
|
if (namePreset.second.m_multiPreset.GetPresetId() == presetId)
|
|
{
|
|
if (settingsFilePathOut)
|
|
{
|
|
*settingsFilePathOut = namePreset.second.m_presetFilePath;
|
|
}
|
|
return namePreset.second.m_multiPreset.GetPreset(platform);
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
const BuilderSettings* BuilderSettingManager::GetBuilderSetting(const PlatformName& platform)
|
|
{
|
|
if (m_builderSettings.find(platform) != m_builderSettings.end())
|
|
{
|
|
return &m_builderSettings[platform];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const PlatformNameList BuilderSettingManager::GetPlatformList()
|
|
{
|
|
PlatformNameList platforms;
|
|
|
|
for (auto& builderSetting : m_builderSettings)
|
|
{
|
|
if (builderSetting.second.m_enablePlatform)
|
|
{
|
|
platforms.push_back(builderSetting.first);
|
|
}
|
|
}
|
|
|
|
return platforms;
|
|
}
|
|
|
|
const AZStd::map <FileMask, AZStd::set<PresetName>>& BuilderSettingManager::GetPresetFilterMap()
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
return m_presetFilterMap;
|
|
}
|
|
|
|
const AZ::Uuid BuilderSettingManager::GetPresetIdFromName(const PresetName& presetName)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
|
|
auto itr = m_presets.find(presetName);
|
|
|
|
if (itr != m_presets.end())
|
|
{
|
|
return itr->second.m_multiPreset.GetPresetId();
|
|
}
|
|
|
|
return AZ::Uuid::CreateNull();
|
|
}
|
|
|
|
const PresetName BuilderSettingManager::GetPresetNameFromId(const AZ::Uuid& presetId)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
|
|
for (const auto& itr : m_presets)
|
|
{
|
|
if (itr.second.m_multiPreset.GetPresetId() == presetId)
|
|
{
|
|
return itr.second.m_multiPreset.GetPresetName();
|
|
}
|
|
}
|
|
|
|
return "Unknown";
|
|
}
|
|
|
|
void BuilderSettingManager::ClearSettings()
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
m_presetFilterMap.clear();
|
|
m_builderSettings.clear();
|
|
m_presets.clear();
|
|
m_defaultPresetByFileMask.clear();
|
|
}
|
|
|
|
StringOutcome BuilderSettingManager::LoadConfig()
|
|
{
|
|
StringOutcome outcome = STRING_OUTCOME_ERROR("");
|
|
|
|
auto fileIoBase = AZ::IO::FileIOBase::GetInstance();
|
|
if (fileIoBase == nullptr)
|
|
{
|
|
return AZ::Failure(AZStd::string("File IO instance needs to be initialized to resolve ImageProcessing builder file aliases"));
|
|
}
|
|
|
|
// Construct the default setting path
|
|
|
|
AZ::IO::FixedMaxPath defaultConfigFolder;
|
|
if (auto engineRoot = fileIoBase->ResolvePath("@engroot@"); engineRoot.has_value())
|
|
{
|
|
defaultConfigFolder = *engineRoot;
|
|
defaultConfigFolder /= s_defaultConfigRelativeFolder;
|
|
}
|
|
|
|
AZ::IO::FixedMaxPath projectConfigFolder;
|
|
if (auto sourceGameRoot = fileIoBase->ResolvePath("@devassets@"); sourceGameRoot.has_value())
|
|
{
|
|
projectConfigFolder = *sourceGameRoot;
|
|
projectConfigFolder /= s_projectConfigRelativeFolder;
|
|
}
|
|
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
ClearSettings();
|
|
|
|
outcome = LoadSettings((projectConfigFolder / s_builderSettingFileName).Native());
|
|
|
|
if (!outcome.IsSuccess())
|
|
{
|
|
outcome = LoadSettings((defaultConfigFolder / s_builderSettingFileName).Native());
|
|
}
|
|
|
|
if (outcome.IsSuccess())
|
|
{
|
|
// Load presets in default folder first, then load from project folder.
|
|
// The same presets which loaded last will overwrite previous loaded one.
|
|
LoadPresets(defaultConfigFolder.Native());
|
|
LoadPresets(projectConfigFolder.Native());
|
|
|
|
// Regenerate file mask mapping after all presets loaded
|
|
RegenerateMappings();
|
|
}
|
|
|
|
return outcome;
|
|
}
|
|
|
|
void BuilderSettingManager::LoadPresets(AZStd::string_view presetFolder)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
|
|
QDirIterator it(presetFolder.data(), QStringList() << "*.preset", QDir::Files, QDirIterator::NoIteratorFlags);
|
|
while (it.hasNext())
|
|
{
|
|
QString filePath = it.next();
|
|
QFileInfo fileInfo = it.fileInfo();
|
|
|
|
MultiplatformPresetSettings preset;
|
|
auto result = AZ::JsonSerializationUtils::LoadObjectFromFile(preset, filePath.toUtf8().data());
|
|
if (!result.IsSuccess())
|
|
{
|
|
AZ_Warning("Image Processing", false, "Failed to load preset file %s. Error: %s",
|
|
filePath.toUtf8().data(), result.GetError().c_str());
|
|
}
|
|
|
|
PresetName presetName(fileInfo.baseName().toUtf8().data());
|
|
|
|
AZ_Warning("Image Processing", presetName == preset.GetPresetName(), "Preset file name '%s' is not"
|
|
" same as preset name '%s'. Using preset file name as preset name",
|
|
filePath.toUtf8().data(), preset.GetPresetName().c_str());
|
|
|
|
preset.SetPresetName(presetName);
|
|
|
|
m_presets[presetName] = PresetEntry{preset, filePath.toUtf8().data()};
|
|
}
|
|
}
|
|
|
|
StringOutcome BuilderSettingManager::LoadConfigFromFolder(AZStd::string_view configFolder)
|
|
{
|
|
// Load builder settings
|
|
AZStd::string settingFilePath = AZStd::string::format("%.*s%s", aznumeric_cast<int>(configFolder.size()),
|
|
configFolder.data(), s_builderSettingFileName);
|
|
auto result = LoadSettings(settingFilePath);
|
|
|
|
// Load presets
|
|
if (result.IsSuccess())
|
|
{
|
|
LoadPresets(configFolder);
|
|
RegenerateMappings();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
StringOutcome BuilderSettingManager::LoadSettings(AZStd::string_view filepath)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
|
|
auto result = AZ::JsonSerializationUtils::LoadObjectFromFile(*this, filepath);
|
|
|
|
if (!result.IsSuccess())
|
|
{
|
|
return STRING_OUTCOME_ERROR(result.GetError());
|
|
}
|
|
|
|
//enable builder settings for enabled restricted platforms. These settings should be disabled by default in the setting file
|
|
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
|
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3) \
|
|
for (auto& buildSetting : m_builderSettings) \
|
|
{ \
|
|
if (ImageProcess##PrivateName::DoesSupport(buildSetting.first)) \
|
|
{ \
|
|
buildSetting.second.m_enablePlatform = true; \
|
|
break; \
|
|
} \
|
|
}
|
|
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
|
|
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
|
|
#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
|
|
|
|
return STRING_OUTCOME_SUCCESS;
|
|
}
|
|
|
|
StringOutcome BuilderSettingManager::WriteSettings(AZStd::string_view filepath)
|
|
{
|
|
AZ::JsonSerializerSettings saveSettings;
|
|
saveSettings.m_keepDefaults = true;
|
|
auto result = AZ::JsonSerializationUtils::SaveObjectToFile(this, filepath,
|
|
(BuilderSettingManager*)nullptr, &saveSettings);
|
|
if (!result.IsSuccess())
|
|
{
|
|
return STRING_OUTCOME_ERROR(result.GetError());
|
|
}
|
|
|
|
return STRING_OUTCOME_SUCCESS;
|
|
}
|
|
|
|
const AZStd::string& BuilderSettingManager::GetAnalysisFingerprint() const
|
|
{
|
|
return m_analysisFingerprint;
|
|
}
|
|
|
|
void BuilderSettingManager::RegenerateMappings()
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
|
|
|
AZStd::string noFilter = AZStd::string();
|
|
|
|
m_presetFilterMap.clear();
|
|
|
|
for (const auto& presetIter : m_presets)
|
|
{
|
|
const MultiplatformPresetSettings& multiPreset = presetIter.second.m_multiPreset;
|
|
const PresetSettings& preset = multiPreset.GetDefaultPreset();
|
|
|
|
//Put into no filter preset list
|
|
m_presetFilterMap[noFilter].insert(preset.m_name);
|
|
|
|
//Put into file mask preset list if any
|
|
for (const PlatformName& filemask : preset.m_fileMasks)
|
|
{
|
|
if (filemask.empty() || filemask[0] != FileMaskDelimiter)
|
|
{
|
|
AZ_Warning("Image Processing", false, "File mask '%s' is invalid. It must start with '%c'.", filemask.c_str(), FileMaskDelimiter);
|
|
continue;
|
|
}
|
|
else if (filemask.size() < 2)
|
|
{
|
|
AZ_Warning("Image Processing", false, "File mask '%s' is invalid. The '%c' must be followed by at least one other character.", filemask.c_str());
|
|
continue;
|
|
}
|
|
else if (filemask.find(FileMaskDelimiter, 1) != AZStd::string::npos)
|
|
{
|
|
AZ_Warning("Image Processing", false, "File mask '%s' is invalid. It must contain only a single '%c' character.", filemask.c_str(), FileMaskDelimiter);
|
|
continue;
|
|
}
|
|
m_presetFilterMap[filemask].insert(preset.m_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BuilderSettingManager::MetafilePathFromImagePath(AZStd::string_view imagePath, AZStd::string& metafilePath)
|
|
{
|
|
// Determine if we have a meta file
|
|
AZ::IO::LocalFileIO fileIO;
|
|
|
|
AZStd::string settingFilePath = AZStd::string::format("%.*s%s", aznumeric_cast<int>(imagePath.size()),
|
|
imagePath.data(), TextureSettings::ExtensionName);
|
|
if (fileIO.Exists(settingFilePath.c_str()))
|
|
{
|
|
metafilePath = settingFilePath;
|
|
return;
|
|
}
|
|
|
|
metafilePath = AZStd::string();
|
|
}
|
|
|
|
AZStd::string GetFileMask(AZStd::string_view imageFilePath)
|
|
{
|
|
//get file name
|
|
AZStd::string fileName;
|
|
QString lowerFileName = imageFilePath.data();
|
|
lowerFileName = lowerFileName.toLower();
|
|
AzFramework::StringFunc::Path::GetFileName(lowerFileName.toUtf8().constData(), fileName);
|
|
|
|
//get the substring from last '_'
|
|
size_t lastUnderScore = fileName.find_last_of(FileMaskDelimiter);
|
|
if (lastUnderScore != AZStd::string::npos)
|
|
{
|
|
return fileName.substr(lastUnderScore);
|
|
}
|
|
|
|
return AZStd::string();
|
|
}
|
|
|
|
AZ::Uuid BuilderSettingManager::GetSuggestedPreset(AZStd::string_view imageFilePath, IImageObjectPtr imageFromFile)
|
|
{
|
|
//load the image to get its size for later use
|
|
IImageObjectPtr image = imageFromFile;
|
|
//if the input image is empty we will try to load it from the path
|
|
if (imageFromFile == nullptr)
|
|
{
|
|
image = IImageObjectPtr(LoadImageFromFile(imageFilePath));
|
|
}
|
|
|
|
if (image == nullptr)
|
|
{
|
|
return AZ::Uuid::CreateNull();
|
|
}
|
|
|
|
//get file mask of this image file
|
|
AZStd::string fileMask = GetFileMask(imageFilePath);
|
|
|
|
AZ::Uuid outPreset = AZ::Uuid::CreateNull();
|
|
|
|
//check default presets for some file masks
|
|
if (m_defaultPresetByFileMask.find(fileMask) != m_defaultPresetByFileMask.end())
|
|
{
|
|
outPreset = m_defaultPresetByFileMask[fileMask];
|
|
}
|
|
|
|
//use the preset filter map to find
|
|
if (outPreset.IsNull() && !fileMask.empty())
|
|
{
|
|
auto& presetFilterMap = GetPresetFilterMap();
|
|
if (presetFilterMap.find(fileMask) != presetFilterMap.end())
|
|
{
|
|
AZStd::string presetName = *(presetFilterMap.find(fileMask)->second.begin());
|
|
outPreset = GetPresetIdFromName(presetName);
|
|
}
|
|
}
|
|
|
|
const PresetSettings* presetInfo = nullptr;
|
|
|
|
if (!outPreset.IsNull())
|
|
{
|
|
presetInfo = GetPreset(outPreset);
|
|
|
|
//special case for cubemap
|
|
if (presetInfo && presetInfo->m_cubemapSetting)
|
|
{
|
|
// If it's not a latitude-longitude map or it doesn't match any cubemap layouts then reset its preset
|
|
if (!IsValidLatLongMap(image) && CubemapLayout::GetCubemapLayoutInfo(image) == nullptr)
|
|
{
|
|
outPreset = AZ::Uuid::CreateNull();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (outPreset.IsNull())
|
|
{
|
|
if (image->GetAlphaContent() == EAlphaContent::eAlphaContent_Absent)
|
|
{
|
|
outPreset = m_defaultPreset;
|
|
}
|
|
else
|
|
{
|
|
outPreset = m_defaultPresetAlpha;
|
|
}
|
|
}
|
|
|
|
//get the pixel format for selected preset
|
|
presetInfo = GetPreset(outPreset);
|
|
|
|
if (presetInfo)
|
|
{
|
|
//valid whether image size work with pixel format
|
|
if (CPixelFormats::GetInstance().IsImageSizeValid(presetInfo->m_pixelFormat,
|
|
image->GetWidth(0), image->GetHeight(0), false))
|
|
{
|
|
return outPreset;
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("Image Processing", false, "Image dimensions are not compatible with preset '%s'. The default preset will be used.", presetInfo->m_name.c_str());
|
|
}
|
|
}
|
|
|
|
//uncompressed one which could be used for almost everything
|
|
return m_defaultPresetNonePOT;
|
|
}
|
|
|
|
bool BuilderSettingManager::DoesSupportPlatform(AZStd::string_view platformId)
|
|
{
|
|
bool rv = m_builderSettings.find(platformId) != m_builderSettings.end();
|
|
return rv;
|
|
}
|
|
|
|
void BuilderSettingManager::SavePresets(AZStd::string_view outputFolder)
|
|
{
|
|
for (const auto& element : m_presets)
|
|
{
|
|
const PresetEntry& presetEntry = element.second;
|
|
AZStd::string fileName = AZStd::string::format("%s.preset", presetEntry.m_multiPreset.GetDefaultPreset().m_name.c_str());
|
|
AZStd::string filePath;
|
|
if (!AzFramework::StringFunc::Path::Join(outputFolder.data(), fileName.c_str(), filePath))
|
|
{
|
|
AZ_Warning("Image Processing", false, "Failed to construct path with folder '%.*s' and file: '%s' to save preset",
|
|
aznumeric_cast<int>(outputFolder.size()), outputFolder.data(), filePath.c_str());
|
|
continue;
|
|
}
|
|
auto result = AZ::JsonSerializationUtils::SaveObjectToFile(&presetEntry.m_multiPreset, filePath);
|
|
if (!result.IsSuccess())
|
|
{
|
|
AZ_Warning("Image Processing", false, "Failed to save preset '%s' to file '%s'. Error: %s",
|
|
presetEntry.m_multiPreset.GetDefaultPreset().m_name.c_str(), filePath.c_str(), result.GetError().c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace ImageProcessingAtom
|