|
|
|
@@ -11,6 +11,7 @@
|
|
|
|
|
#include <Common/JsonTestUtils.h>
|
|
|
|
|
#include <Common/ShaderAssetTestUtils.h>
|
|
|
|
|
#include <Common/ErrorMessageFinder.h>
|
|
|
|
|
#include <Common/SerializeTester.h>
|
|
|
|
|
#include <Material/MaterialAssetTestUtils.h>
|
|
|
|
|
|
|
|
|
|
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
|
|
|
@@ -65,9 +66,29 @@ namespace UnitTest
|
|
|
|
|
m_testShaderAsset = CreateTestShaderAsset(Uuid::CreateRandom(), m_testMaterialSrgLayout);
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.shader", m_testShaderAsset.GetId());
|
|
|
|
|
|
|
|
|
|
// The MaterialSourceData relies on both MaterialTypeSourceData and MaterialTypeAsset. We have to make sure the
|
|
|
|
|
// .materialtype file is present on disk, and that the MaterialTypeAsset is available through the asset database stub...
|
|
|
|
|
m_testMaterialTypeAsset = CreateTestMaterialTypeAsset(Uuid::CreateRandom());
|
|
|
|
|
|
|
|
|
|
// Since this test doesn't actually instantiate a Material, it won't need to instantiate this ImageAsset, so all we
|
|
|
|
|
// need is an asset reference with a valid ID.
|
|
|
|
|
m_testImageAsset = Data::Asset<ImageAsset>{ Data::AssetId{Uuid::CreateRandom(), StreamingImageAsset::GetImageAssetSubId()}, azrtti_typeid<StreamingImageAsset>() };
|
|
|
|
|
|
|
|
|
|
// Register the test assets with the AssetSystemStub so CreateMaterialAsset() can use AssetUtils.
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.materialtype", m_testMaterialTypeAsset.GetId());
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.streamingimage", m_testImageAsset.GetId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TearDown() override
|
|
|
|
|
{
|
|
|
|
|
m_testMaterialTypeAsset.Reset();
|
|
|
|
|
m_testMaterialSrgLayout = nullptr;
|
|
|
|
|
m_testShaderAsset.Reset();
|
|
|
|
|
m_testImageAsset.Reset();
|
|
|
|
|
|
|
|
|
|
RPITestFixture::TearDown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Data::Asset<MaterialTypeAsset> CreateTestMaterialTypeAsset(Data::AssetId assetId)
|
|
|
|
|
{
|
|
|
|
|
const char* materialTypeJson = R"(
|
|
|
|
|
{
|
|
|
|
|
"version": 10,
|
|
|
|
@@ -122,29 +143,10 @@ namespace UnitTest
|
|
|
|
|
}
|
|
|
|
|
)";
|
|
|
|
|
|
|
|
|
|
AZ::Utils::WriteFile(materialTypeJson, "@exefolder@/Temp/test.materialtype");
|
|
|
|
|
|
|
|
|
|
MaterialTypeSourceData materialTypeSourceData;
|
|
|
|
|
LoadTestDataFromJson(materialTypeSourceData, materialTypeJson);
|
|
|
|
|
m_testMaterialTypeAsset = materialTypeSourceData.CreateMaterialTypeAsset(Uuid::CreateRandom()).TakeValue();
|
|
|
|
|
|
|
|
|
|
// Since this test doesn't actually instantiate a Material, it won't need to instantiate this ImageAsset, so all we
|
|
|
|
|
// need is an asset reference with a valid ID.
|
|
|
|
|
m_testImageAsset = Data::Asset<ImageAsset>{ Data::AssetId{Uuid::CreateRandom(), StreamingImageAsset::GetImageAssetSubId()}, azrtti_typeid<StreamingImageAsset>() };
|
|
|
|
|
|
|
|
|
|
// Register the test assets with the AssetSystemStub so CreateMaterialAsset() can use AssetUtils.
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.materialtype", m_testMaterialTypeAsset.GetId());
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.streamingimage", m_testImageAsset.GetId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TearDown() override
|
|
|
|
|
{
|
|
|
|
|
m_testMaterialTypeAsset.Reset();
|
|
|
|
|
m_testMaterialSrgLayout = nullptr;
|
|
|
|
|
m_testShaderAsset.Reset();
|
|
|
|
|
m_testImageAsset.Reset();
|
|
|
|
|
|
|
|
|
|
RPITestFixture::TearDown();
|
|
|
|
|
return materialTypeSourceData.CreateMaterialTypeAsset(assetId).TakeValue();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -180,7 +182,10 @@ namespace UnitTest
|
|
|
|
|
|
|
|
|
|
Data::Asset<MaterialAsset> materialAsset = materialAssetOutcome.GetValue();
|
|
|
|
|
|
|
|
|
|
// The order here is based on the order in the MaterialTypeSourceData, as added to the the MaterialTypeAssetCreator.
|
|
|
|
|
EXPECT_TRUE(materialAsset->IsFinalized());
|
|
|
|
|
EXPECT_EQ(0, materialAsset->GetRawPropertyValues().size()); // A pre-baked material has no need for the original raw property names and values
|
|
|
|
|
|
|
|
|
|
// The order here is based on the order in the MaterialTypeSourceData, as added to the MaterialTypeAssetCreator.
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[0].GetValue<bool>(), true);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[1].GetValue<int32_t>(), -10);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[2].GetValue<uint32_t>(), 25u);
|
|
|
|
@@ -192,6 +197,105 @@ namespace UnitTest
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue<Data::Asset<ImageAsset>>(), m_testImageAsset);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue<uint32_t>(), 1u);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(MaterialSourceDataTests, CreateMaterialAsset_DeferredBake)
|
|
|
|
|
{
|
|
|
|
|
// This test is similar to CreateMaterialAsset_BasicProperties but uses MaterialAssetProcessingMode::DeferredBake instead of PreBake.
|
|
|
|
|
|
|
|
|
|
Data::AssetId materialTypeAssetId = Uuid::CreateRandom();
|
|
|
|
|
|
|
|
|
|
// This material type asset will be known by the asset system (stub) but doesn't exist in the AssetManager.
|
|
|
|
|
// This demonstrates that the CreateMaterialAsset does not attempt to access the MaterialTypeAsset data in MaterialAssetProcessingMode::DeferredBake.
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("testDeferredBake.materialtype", materialTypeAssetId);
|
|
|
|
|
|
|
|
|
|
MaterialSourceData sourceData;
|
|
|
|
|
|
|
|
|
|
sourceData.m_materialType = "testDeferredBake.materialtype";
|
|
|
|
|
AddPropertyGroup(sourceData, "general");
|
|
|
|
|
AddProperty(sourceData, "general", "MyBool" , true);
|
|
|
|
|
AddProperty(sourceData, "general", "MyInt" , -10);
|
|
|
|
|
AddProperty(sourceData, "general", "MyUInt" , 25u);
|
|
|
|
|
AddProperty(sourceData, "general", "MyFloat" , 1.5f);
|
|
|
|
|
AddProperty(sourceData, "general", "MyColor" , AZ::Color{0.1f, 0.2f, 0.3f, 0.4f});
|
|
|
|
|
AddProperty(sourceData, "general", "MyFloat2", AZ::Vector2(2.1f, 2.2f));
|
|
|
|
|
AddProperty(sourceData, "general", "MyFloat3", AZ::Vector3(3.1f, 3.2f, 3.3f));
|
|
|
|
|
AddProperty(sourceData, "general", "MyFloat4", AZ::Vector4(4.1f, 4.2f, 4.3f, 4.4f));
|
|
|
|
|
AddProperty(sourceData, "general", "MyImage" , AZStd::string("@exefolder@/Temp/test.streamingimage"));
|
|
|
|
|
AddProperty(sourceData, "general", "MyEnum" , AZStd::string("Enum1"));
|
|
|
|
|
|
|
|
|
|
auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetOutcome.IsSuccess());
|
|
|
|
|
|
|
|
|
|
Data::Asset<MaterialAsset> materialAsset = materialAssetOutcome.GetValue();
|
|
|
|
|
|
|
|
|
|
EXPECT_FALSE(materialAsset->IsFinalized());
|
|
|
|
|
// Note we avoid calling GetPropertyValues() because that will auto-finalize the material. We want to check its raw property values first.
|
|
|
|
|
|
|
|
|
|
auto findRawPropertyValue = [materialAsset](const char* propertyId)
|
|
|
|
|
{
|
|
|
|
|
auto iter = AZStd::find_if(materialAsset->GetRawPropertyValues().begin(), materialAsset->GetRawPropertyValues().end(), [propertyId](const AZStd::pair<Name, MaterialPropertyValue>& pair)
|
|
|
|
|
{
|
|
|
|
|
return pair.first == AZ::Name{propertyId};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (iter == materialAsset->GetRawPropertyValues().end())
|
|
|
|
|
{
|
|
|
|
|
return MaterialPropertyValue{};
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return iter->second;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto checkRawPropertyValues = [findRawPropertyValue, this]()
|
|
|
|
|
{
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyBool" ).GetValue<bool>(), true);
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyInt" ).GetValue<int32_t>(), -10);
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyUInt" ).GetValue<uint32_t>(), 25u);
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyFloat" ).GetValue<float>(), 1.5f);
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyFloat2").GetValue<Vector2>(), Vector2(2.1f, 2.2f));
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyFloat3").GetValue<Vector3>(), Vector3(3.1f, 3.2f, 3.3f));
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyFloat4").GetValue<Vector4>(), Vector4(4.1f, 4.2f, 4.3f, 4.4f));
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyColor" ).GetValue<Color>(), Color(0.1f, 0.2f, 0.3f, 0.4f));
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyImage" ).GetValue<Data::Asset<ImageAsset>>(), m_testImageAsset);
|
|
|
|
|
// The raw value for an enum is the original string, not the numerical value, because the material type holds the necessary metadata to match the name to the value.
|
|
|
|
|
EXPECT_EQ(findRawPropertyValue("general.MyEnum" ).GetValue<AZStd::string>(), AZStd::string("Enum1"));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// We check the raw property values before the material type asset is even available
|
|
|
|
|
checkRawPropertyValues();
|
|
|
|
|
|
|
|
|
|
// Now we'll create the material type asset in memory so the material will have what it needs to finalize itself.
|
|
|
|
|
Data::Asset<MaterialTypeAsset> testMaterialTypeAsset = CreateTestMaterialTypeAsset(materialTypeAssetId);
|
|
|
|
|
|
|
|
|
|
// The MaterialAsset is still holding an reference to an unloaded asset, so we run it through the serializer which causes the loaded MaterialAsset
|
|
|
|
|
// to have access to the testMaterialTypeAsset. This is similar to how the AP would save the MaterialAsset to the cache and the runtime would load it.
|
|
|
|
|
SerializeTester<RPI::MaterialAsset> tester(GetSerializeContext());
|
|
|
|
|
tester.SerializeOut(materialAsset.Get());
|
|
|
|
|
materialAsset = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading});
|
|
|
|
|
|
|
|
|
|
// We check the raw property values again on the loaded data, showing that the same data is available in the original un-finalized state.
|
|
|
|
|
checkRawPropertyValues();
|
|
|
|
|
|
|
|
|
|
// The material will automatically finalize itself when the properties are accessed.
|
|
|
|
|
EXPECT_FALSE(materialAsset->IsFinalized());
|
|
|
|
|
materialAsset->GetPropertyValues();
|
|
|
|
|
EXPECT_TRUE(materialAsset->IsFinalized());
|
|
|
|
|
|
|
|
|
|
// Now all the property values should be available through the main GetPropertyValues() API.
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[0].GetValue<bool>(), true);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[1].GetValue<int32_t>(), -10);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[2].GetValue<uint32_t>(), 25u);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[3].GetValue<float>(), 1.5f);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[4].GetValue<Vector2>(), Vector2(2.1f, 2.2f));
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[5].GetValue<Vector3>(), Vector3(3.1f, 3.2f, 3.3f));
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[6].GetValue<Vector4>(), Vector4(4.1f, 4.2f, 4.3f, 4.4f));
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[7].GetValue<Color>(), Color(0.1f, 0.2f, 0.3f, 0.4f));
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue<Data::Asset<ImageAsset>>(), m_testImageAsset);
|
|
|
|
|
EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue<uint32_t>(), 1u);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CheckEqual(MaterialSourceData& a, MaterialSourceData& b)
|
|
|
|
|
{
|
|
|
|
@@ -546,16 +650,19 @@ namespace UnitTest
|
|
|
|
|
|
|
|
|
|
auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel1.IsSuccess());
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel1.GetValue()->IsFinalized());
|
|
|
|
|
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetValue().GetId());
|
|
|
|
|
|
|
|
|
|
auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel2.IsSuccess());
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel2.GetValue()->IsFinalized());
|
|
|
|
|
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetValue().GetId());
|
|
|
|
|
|
|
|
|
|
auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel3.IsSuccess());
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel3.GetValue()->IsFinalized());
|
|
|
|
|
|
|
|
|
|
auto layout = m_testMaterialTypeAsset->GetMaterialPropertiesLayout();
|
|
|
|
|
MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat"));
|
|
|
|
@@ -582,6 +689,101 @@ namespace UnitTest
|
|
|
|
|
EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue<Vector2>(), Vector2(4.1f, 4.2f));
|
|
|
|
|
EXPECT_EQ(properties[myColor.GetIndex()].GetValue<Color>(), Color(0.15f, 0.25f, 0.35f, 0.45f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MultiLevelDataInheritance_DeferredBake)
|
|
|
|
|
{
|
|
|
|
|
// This test is similar to CreateMaterialAsset_MultiLevelDataInheritance but uses MaterialAssetProcessingMode::DeferredBake instead of PreBake.
|
|
|
|
|
|
|
|
|
|
Data::AssetId materialTypeAssetId = Uuid::CreateRandom();
|
|
|
|
|
|
|
|
|
|
// This material type asset will be known by the asset system (stub) but doesn't exist in the AssetManager.
|
|
|
|
|
// This demonstrates that the CreateMaterialAsset does not attempt to access the MaterialTypeAsset data in MaterialAssetProcessingMode::DeferredBake.
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("testDeferredBake.materialtype", materialTypeAssetId);
|
|
|
|
|
|
|
|
|
|
MaterialSourceData sourceDataLevel1;
|
|
|
|
|
sourceDataLevel1.m_materialType = "testDeferredBake.materialtype";
|
|
|
|
|
AddPropertyGroup(sourceDataLevel1, "general");
|
|
|
|
|
AddProperty(sourceDataLevel1, "general", "MyFloat", 1.5f);
|
|
|
|
|
AddProperty(sourceDataLevel1, "general", "MyColor", AZ::Color{0.1f, 0.2f, 0.3f, 0.4f});
|
|
|
|
|
|
|
|
|
|
MaterialSourceData sourceDataLevel2;
|
|
|
|
|
sourceDataLevel2.m_materialType = "testDeferredBake.materialtype";
|
|
|
|
|
sourceDataLevel2.m_parentMaterial = "level1.material";
|
|
|
|
|
AddPropertyGroup(sourceDataLevel2, "general");
|
|
|
|
|
AddProperty(sourceDataLevel2, "general", "MyColor", AZ::Color{0.15f, 0.25f, 0.35f, 0.45f});
|
|
|
|
|
AddProperty(sourceDataLevel2, "general", "MyFloat2", AZ::Vector2{4.1f, 4.2f});
|
|
|
|
|
|
|
|
|
|
MaterialSourceData sourceDataLevel3;
|
|
|
|
|
sourceDataLevel3.m_materialType = "testDeferredBake.materialtype";
|
|
|
|
|
sourceDataLevel3.m_parentMaterial = "level2.material";
|
|
|
|
|
AddPropertyGroup(sourceDataLevel3, "general");
|
|
|
|
|
AddProperty(sourceDataLevel3, "general", "MyFloat", 3.5f);
|
|
|
|
|
|
|
|
|
|
auto materialAssetLevel1Result = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel1Result.IsSuccess());
|
|
|
|
|
Data::Asset<MaterialAsset> materialAssetLevel1 = materialAssetLevel1Result.TakeValue();
|
|
|
|
|
EXPECT_FALSE(materialAssetLevel1->IsFinalized());
|
|
|
|
|
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetId());
|
|
|
|
|
|
|
|
|
|
auto materialAssetLevel2Result = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel2Result.IsSuccess());
|
|
|
|
|
Data::Asset<MaterialAsset> materialAssetLevel2 = materialAssetLevel2Result.TakeValue();
|
|
|
|
|
EXPECT_FALSE(materialAssetLevel2->IsFinalized());
|
|
|
|
|
|
|
|
|
|
m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetId());
|
|
|
|
|
|
|
|
|
|
auto materialAssetLevel3Result = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true);
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel3Result.IsSuccess());
|
|
|
|
|
Data::Asset<MaterialAsset> materialAssetLevel3 = materialAssetLevel3Result.TakeValue();
|
|
|
|
|
EXPECT_FALSE(materialAssetLevel3->IsFinalized());
|
|
|
|
|
|
|
|
|
|
// Now we'll create the material type asset in memory so the materials will have what they need to finalize.
|
|
|
|
|
Data::Asset<MaterialTypeAsset> testMaterialTypeAsset = CreateTestMaterialTypeAsset(materialTypeAssetId);
|
|
|
|
|
|
|
|
|
|
auto layout = testMaterialTypeAsset->GetMaterialPropertiesLayout();
|
|
|
|
|
MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat"));
|
|
|
|
|
MaterialPropertyIndex myFloat2 = layout->FindPropertyIndex(Name("general.MyFloat2"));
|
|
|
|
|
MaterialPropertyIndex myColor = layout->FindPropertyIndex(Name("general.MyColor"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The MaterialAsset is still holding an reference to an unloaded asset, so we run it through the serializer which causes the loaded MaterialAsset
|
|
|
|
|
// to have access to the testMaterialTypeAsset. This is similar to how the AP would save the MaterialAsset to the cache and the runtime would load it.
|
|
|
|
|
SerializeTester<RPI::MaterialAsset> tester(GetSerializeContext());
|
|
|
|
|
tester.SerializeOut(materialAssetLevel1.Get());
|
|
|
|
|
materialAssetLevel1 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading});
|
|
|
|
|
tester.SerializeOut(materialAssetLevel2.Get());
|
|
|
|
|
materialAssetLevel2 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading});
|
|
|
|
|
tester.SerializeOut(materialAssetLevel3.Get());
|
|
|
|
|
materialAssetLevel3 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The properties will finalize automatically when we call GetPropertyValues()...
|
|
|
|
|
|
|
|
|
|
AZStd::array_view<MaterialPropertyValue> properties;
|
|
|
|
|
|
|
|
|
|
// Check level 1 properties
|
|
|
|
|
properties = materialAssetLevel1->GetPropertyValues();
|
|
|
|
|
EXPECT_EQ(properties[myFloat.GetIndex()].GetValue<float>(), 1.5f);
|
|
|
|
|
EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue<Vector2>(), Vector2(0.0f, 0.0f));
|
|
|
|
|
EXPECT_EQ(properties[myColor.GetIndex()].GetValue<Color>(), Color(0.1f, 0.2f, 0.3f, 0.4f));
|
|
|
|
|
|
|
|
|
|
// Check level 2 properties
|
|
|
|
|
properties = materialAssetLevel2->GetPropertyValues();
|
|
|
|
|
EXPECT_EQ(properties[myFloat.GetIndex()].GetValue<float>(), 1.5f);
|
|
|
|
|
EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue<Vector2>(), Vector2(4.1f, 4.2f));
|
|
|
|
|
EXPECT_EQ(properties[myColor.GetIndex()].GetValue<Color>(), Color(0.15f, 0.25f, 0.35f, 0.45f));
|
|
|
|
|
|
|
|
|
|
// Check level 3 properties
|
|
|
|
|
properties = materialAssetLevel3->GetPropertyValues();
|
|
|
|
|
EXPECT_EQ(properties[myFloat.GetIndex()].GetValue<float>(), 3.5f);
|
|
|
|
|
EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue<Vector2>(), Vector2(4.1f, 4.2f));
|
|
|
|
|
EXPECT_EQ(properties[myColor.GetIndex()].GetValue<Color>(), Color(0.15f, 0.25f, 0.35f, 0.45f));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel1->IsFinalized());
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel2->IsFinalized());
|
|
|
|
|
EXPECT_TRUE(materialAssetLevel3->IsFinalized());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MultiLevelDataInheritance_Error_MaterialTypesDontMatch)
|
|
|
|
|
{
|
|
|
|
|