MaterialPropertyValueSourceData.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h>
  9. #include <Atom/RPI.Edit/Material/MaterialPropertyValueSourceDataSerializer.h>
  10. #include <Atom/RPI.Edit/Material/MaterialUtils.h>
  11. #include <AzCore/Math/Vector2.h>
  12. #include <AzCore/Math/Vector3.h>
  13. #include <AzCore/Math/Vector4.h>
  14. #include <AzCore/Math/Color.h>
  15. #include <AzCore/Serialization/Json/BaseJsonSerializer.h>
  16. #include <AzCore/Serialization/Json/JsonSerializationResult.h>
  17. #include <AzCore/Serialization/Json/JsonSerialization.h>
  18. #include <AzCore/Serialization/Json/RegistrationContext.h>
  19. #include <AzCore/Serialization/Json/StackedString.h>
  20. namespace AZ
  21. {
  22. namespace RPI
  23. {
  24. void MaterialPropertyValueSourceData::Reflect(ReflectContext* context)
  25. {
  26. if (JsonRegistrationContext* jsonContext = azrtti_cast<JsonRegistrationContext*>(context))
  27. {
  28. jsonContext->Serializer<JsonMaterialPropertyValueSourceDataSerializer>()->HandlesType<MaterialPropertyValueSourceData>();
  29. }
  30. if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
  31. {
  32. serializeContext->Class<MaterialPropertyValueSourceData>()
  33. ->Version(1);
  34. }
  35. }
  36. bool MaterialPropertyValueSourceData::Resolve(const MaterialPropertiesLayout& propertiesLayout, const AZ::Name& materialPropertyName) const
  37. {
  38. const MaterialPropertyDescriptor* propertyDescriptor = propertiesLayout.GetPropertyDescriptor(propertiesLayout.FindPropertyIndex(materialPropertyName));
  39. if (!propertyDescriptor)
  40. {
  41. AZ_Error("MaterialPropertyValueSourceData", false, "Material property '%s' can't be found.", materialPropertyName.GetCStr());
  42. return false;
  43. }
  44. AZ::TypeId typeId = propertyDescriptor->GetStorageDataTypeId();
  45. auto iter = m_possibleValues.find(typeId);
  46. if (iter != m_possibleValues.end())
  47. {
  48. m_resolvedValue = iter->second;
  49. }
  50. if (!m_resolvedValue.IsValid())
  51. {
  52. AZ_Error("MaterialPropertyValueSourceData", false, "Value for material property '%s' is invalid. %s is required.", materialPropertyName.GetCStr(), ToString(propertyDescriptor->GetDataType()));
  53. return false;
  54. }
  55. return true;
  56. }
  57. bool MaterialPropertyValueSourceData::IsResolved() const
  58. {
  59. return m_resolvedValue.IsValid();
  60. }
  61. const MaterialPropertyValue& MaterialPropertyValueSourceData::GetValue() const
  62. {
  63. AZ_Assert(IsResolved(), "Value is not resolved. Resolve() or SetValue() should be called first before GetValue().");
  64. return m_resolvedValue;
  65. }
  66. void MaterialPropertyValueSourceData::SetValue(const MaterialPropertyValue& value)
  67. {
  68. m_resolvedValue = AZStd::move(value);
  69. }
  70. bool MaterialPropertyValueSourceData::AreSimilar(const MaterialPropertyValueSourceData& lhs, const MaterialPropertyValueSourceData& rhs)
  71. {
  72. // Special case where both are empty. They are treated equal.
  73. if (!lhs.IsResolved() && !rhs.IsResolved() && lhs.m_possibleValues.empty() && rhs.m_possibleValues.empty())
  74. {
  75. return true;
  76. }
  77. if (lhs.IsResolved() && rhs.IsResolved())
  78. {
  79. return lhs.m_resolvedValue == rhs.m_resolvedValue;
  80. }
  81. else if (lhs.IsResolved())
  82. {
  83. auto possibleValueRhs = rhs.m_possibleValues.find(lhs.m_resolvedValue.GetTypeId());
  84. return (possibleValueRhs != rhs.m_possibleValues.end())
  85. && (lhs.m_resolvedValue == possibleValueRhs->second);
  86. }
  87. else if (rhs.IsResolved())
  88. {
  89. auto possibleValueLhs = lhs.m_possibleValues.find(rhs.m_resolvedValue.GetTypeId());
  90. return (possibleValueLhs != lhs.m_possibleValues.end())
  91. && (possibleValueLhs->second == rhs.m_resolvedValue);
  92. }
  93. else
  94. {
  95. if (lhs.m_possibleValues.size() != rhs.m_possibleValues.size())
  96. {
  97. return false;
  98. }
  99. // Loop through the entire possible value list.
  100. for (auto possibleValueLhs : lhs.m_possibleValues)
  101. {
  102. auto possibleValueRhs = rhs.m_possibleValues.find(possibleValueLhs.first);
  103. if (possibleValueRhs == rhs.m_possibleValues.end()
  104. || (possibleValueLhs.second != possibleValueRhs->second))
  105. {
  106. return false;
  107. }
  108. }
  109. return true;
  110. }
  111. }
  112. } // namespace RPI
  113. } // namespace AZ