|
@@ -28,6 +28,7 @@
|
|
|
|
|
|
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
|
|
|
#include <Atom/RPI.Edit/Material/MaterialConverterBus.h>
|
|
|
+#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
|
|
|
|
|
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
|
|
#include <AzCore/Settings/SettingsRegistry.h>
|
|
@@ -70,28 +71,74 @@ namespace AZ
|
|
|
|
|
|
void MaterialAssetDependenciesComponent::ReportJobDependencies(SceneAPI::JobDependencyList& jobDependencyList, const char* platformIdentifier)
|
|
|
{
|
|
|
- AssetBuilderSDK::SourceFileDependency materialTypeSource;
|
|
|
+ bool conversionEnabled = false;
|
|
|
+ RPI::MaterialConverterBus::BroadcastResult(conversionEnabled, &RPI::MaterialConverterBus::Events::IsEnabled);
|
|
|
+
|
|
|
// Right now, scene file importing only supports a single material type, once that changes, this will have to be re-designed, see ATOM-3554
|
|
|
- RPI::MaterialConverterBus::BroadcastResult(materialTypeSource.m_sourceFileDependencyPath, &RPI::MaterialConverterBus::Events::GetMaterialTypePath);
|
|
|
+ const char* materialTypePath = nullptr;
|
|
|
+ RPI::MaterialConverterBus::BroadcastResult(materialTypePath, &RPI::MaterialConverterBus::Events::GetMaterialTypePath);
|
|
|
|
|
|
- AssetBuilderSDK::JobDependency jobDependency;
|
|
|
- jobDependency.m_jobKey = "Atom Material Builder";
|
|
|
- jobDependency.m_sourceFile = materialTypeSource;
|
|
|
- jobDependency.m_platformIdentifier = platformIdentifier;
|
|
|
- jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order;
|
|
|
-
|
|
|
- if (!materialTypeSource.m_sourceFileDependencyPath.empty())
|
|
|
+ if (conversionEnabled && materialTypePath)
|
|
|
{
|
|
|
+ AssetBuilderSDK::SourceFileDependency materialTypeSource;
|
|
|
+ materialTypeSource.m_sourceFileDependencyPath = materialTypePath;
|
|
|
+
|
|
|
+ AssetBuilderSDK::JobDependency jobDependency;
|
|
|
+ jobDependency.m_jobKey = "Atom Material Builder";
|
|
|
+ jobDependency.m_sourceFile = materialTypeSource;
|
|
|
+ jobDependency.m_platformIdentifier = platformIdentifier;
|
|
|
+ jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order;
|
|
|
+
|
|
|
jobDependencyList.push_back(jobDependency);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ void MaterialAssetDependenciesComponent::AddFingerprintInfo(AZStd::set<AZStd::string>& fingerprintInfo)
|
|
|
+ {
|
|
|
+ // This will cause scene files to be reprocessed whenever the global MaterialConverter settings change.
|
|
|
+
|
|
|
+ bool conversionEnabled = false;
|
|
|
+ RPI::MaterialConverterBus::BroadcastResult(conversionEnabled, &RPI::MaterialConverterBus::Events::IsEnabled);
|
|
|
+ fingerprintInfo.insert(AZStd::string::format("[MaterialConverter enabled=%d]", conversionEnabled));
|
|
|
+
|
|
|
+ if (!conversionEnabled)
|
|
|
+ {
|
|
|
+ AZStd::string defaultMaterialPath;
|
|
|
+ RPI::MaterialConverterBus::BroadcastResult(defaultMaterialPath, &RPI::MaterialConverterBus::Events::GetDefaultMaterialPath);
|
|
|
+ fingerprintInfo.insert(AZStd::string::format("[MaterialConverter defaultMaterial=%s]", defaultMaterialPath.c_str()));
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
void MaterialAssetBuilderComponent::Reflect(ReflectContext* context)
|
|
|
{
|
|
|
if (auto* serialize = azrtti_cast<SerializeContext*>(context))
|
|
|
{
|
|
|
serialize->Class<MaterialAssetBuilderComponent, SceneAPI::SceneCore::ExportingComponent>()
|
|
|
- ->Version(16); // Optional material conversion
|
|
|
+ ->Version(16); // Optional material conversion
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Data::Asset<MaterialAsset> MaterialAssetBuilderComponent::GetDefaultMaterialAsset() const
|
|
|
+ {
|
|
|
+ AZStd::string defaultMaterialPath;
|
|
|
+ RPI::MaterialConverterBus::BroadcastResult(defaultMaterialPath, &RPI::MaterialConverterBus::Events::GetDefaultMaterialPath);
|
|
|
+
|
|
|
+ if (defaultMaterialPath.empty())
|
|
|
+ {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ auto defaultMaterialAssetId = RPI::AssetUtils::MakeAssetId(defaultMaterialPath, 0);
|
|
|
+ if (!defaultMaterialAssetId.IsSuccess())
|
|
|
+ {
|
|
|
+ AZ_Error("MaterialAssetBuilderComponent", false, "Could not find asset '%s'", defaultMaterialPath.c_str());
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return Data::AssetManager::Instance().CreateAsset<RPI::MaterialAsset>(defaultMaterialAssetId.GetValue(), Data::AssetLoadBehaviorNamespace::PreLoad);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -119,8 +166,8 @@ namespace AZ
|
|
|
|
|
|
BindToCall(&MaterialAssetBuilderComponent::BuildMaterials);
|
|
|
}
|
|
|
-
|
|
|
- SceneAPI::Events::ProcessingResult MaterialAssetBuilderComponent::BuildMaterials(MaterialAssetBuilderContext& context) const
|
|
|
+
|
|
|
+ SceneAPI::Events::ProcessingResult MaterialAssetBuilderComponent::ConvertMaterials(MaterialAssetBuilderContext& context) const
|
|
|
{
|
|
|
const auto& scene = context.m_scene;
|
|
|
const Uuid sourceSceneUuid = scene.GetSourceGuid();
|
|
@@ -193,6 +240,64 @@ namespace AZ
|
|
|
|
|
|
return SceneAPI::Events::ProcessingResult::Success;
|
|
|
}
|
|
|
+
|
|
|
+ SceneAPI::Events::ProcessingResult MaterialAssetBuilderComponent::AssignDefaultMaterials(MaterialAssetBuilderContext& context) const
|
|
|
+ {
|
|
|
+ Data::Asset<MaterialAsset> defaultMaterialAsset = GetDefaultMaterialAsset();
|
|
|
+
|
|
|
+ if (!defaultMaterialAsset.GetId().IsValid())
|
|
|
+ {
|
|
|
+ AZ_Warning("MaterialAssetBuilderComponent", false, "Material conversion is disabled but no default material was provided. The model will likely be invisible by default.");
|
|
|
+ // Return success because it's just a warning.
|
|
|
+ return SceneAPI::Events::ProcessingResult::Success;
|
|
|
+ }
|
|
|
+
|
|
|
+ const auto& scene = context.m_scene;
|
|
|
+ const Uuid sourceSceneUuid = scene.GetSourceGuid();
|
|
|
+ const auto& sceneGraph = scene.GetGraph();
|
|
|
+
|
|
|
+ auto names = sceneGraph.GetNameStorage();
|
|
|
+ auto content = sceneGraph.GetContentStorage();
|
|
|
+ auto pairView = SceneAPI::Containers::Views::MakePairView(names, content);
|
|
|
+
|
|
|
+ auto view = SceneAPI::Containers::Views::MakeSceneGraphDownwardsView<
|
|
|
+ SceneAPI::Containers::Views::BreadthFirst>(
|
|
|
+ sceneGraph, sceneGraph.GetRoot(), pairView.cbegin(), true);
|
|
|
+
|
|
|
+ for (const auto& viewIt : view)
|
|
|
+ {
|
|
|
+ if (viewIt.second == nullptr)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (azrtti_istypeof<SceneAPI::DataTypes::IMaterialData>(viewIt.second.get()))
|
|
|
+ {
|
|
|
+ auto materialData = AZStd::static_pointer_cast<const SceneAPI::DataTypes::IMaterialData>(viewIt.second);
|
|
|
+ uint64_t materialUid = materialData->GetUniqueId();
|
|
|
+
|
|
|
+ context.m_outputMaterialsByUid[materialUid] = { defaultMaterialAsset, materialData->GetMaterialName() };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return SceneAPI::Events::ProcessingResult::Success;
|
|
|
+ }
|
|
|
+
|
|
|
+ SceneAPI::Events::ProcessingResult MaterialAssetBuilderComponent::BuildMaterials(MaterialAssetBuilderContext& context) const
|
|
|
+ {
|
|
|
+ bool conversionEnabled = false;
|
|
|
+ RPI::MaterialConverterBus::BroadcastResult(conversionEnabled, &RPI::MaterialConverterBus::Events::IsEnabled);
|
|
|
+
|
|
|
+ if (conversionEnabled)
|
|
|
+ {
|
|
|
+ return ConvertMaterials(context);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return AssignDefaultMaterials(context);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
} // namespace RPI
|
|
|
} // namespace AZ
|
|
|
|