MaterialPropertyValueSerializer.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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/MaterialPropertyValueSerializer.h>
  9. #include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
  10. #include <Atom/RPI.Edit/Material/MaterialPropertySerializer.h>
  11. #include <Atom/RPI.Edit/Material/MaterialPropertyId.h>
  12. #include <AzCore/Math/Color.h>
  13. #include <AzCore/Math/Vector2.h>
  14. #include <AzCore/Math/Vector3.h>
  15. #include <AzCore/Math/Vector4.h>
  16. #include <AzCore/Serialization/Json/BaseJsonSerializer.h>
  17. #include <AzCore/Serialization/Json/JsonSerializationResult.h>
  18. #include <AzCore/Serialization/Json/JsonSerialization.h>
  19. #include <AzCore/Serialization/Json/StackedString.h>
  20. #include <AzCore/Serialization/Json/JsonUtils.h>
  21. namespace AZ
  22. {
  23. namespace RPI
  24. {
  25. AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialPropertyValueSerializer, SystemAllocator);
  26. template<typename T>
  27. JsonSerializationResult::ResultCode JsonMaterialPropertyValueSerializer::LoadVariant(
  28. MaterialPropertyValue& intoValue,
  29. const T& defaultValue,
  30. const rapidjson::Value& inputValue,
  31. JsonDeserializerContext& context)
  32. {
  33. T value = defaultValue;
  34. JsonSerializationResult::ResultCode result = ContinueLoading(&value, azrtti_typeid<T>(), inputValue, context);
  35. intoValue = value;
  36. return result;
  37. }
  38. JsonSerializationResult::Result JsonMaterialPropertyValueSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,
  39. const rapidjson::Value& inputValue, JsonDeserializerContext& context)
  40. {
  41. namespace JSR = JsonSerializationResult;
  42. AZ_Assert(azrtti_typeid<MaterialPropertyValue>() == outputValueTypeId,
  43. "Unable to deserialize material property value to json because the provided type is %s",
  44. outputValueTypeId.ToString<AZStd::string>().c_str());
  45. AZ_UNUSED(outputValueTypeId);
  46. MaterialPropertyValue* property = reinterpret_cast<MaterialPropertyValue*>(outputValue);
  47. AZ_Assert(property, "Output value for JsonMaterialPropertyValueSerializer can't be null.");
  48. JSR::ResultCode result(JSR::Tasks::ReadField);
  49. if (inputValue.IsBool())
  50. {
  51. result.Combine(LoadVariant<bool>(*property, false, inputValue, context));
  52. }
  53. else if (inputValue.IsInt() || inputValue.IsInt64())
  54. {
  55. result.Combine(LoadVariant<int32_t>(*property, 0, inputValue, context));
  56. }
  57. else if (inputValue.IsUint() || inputValue.IsUint64())
  58. {
  59. result.Combine(LoadVariant<uint32_t>(*property, 0u, inputValue, context));
  60. }
  61. else if (inputValue.IsFloat() || inputValue.IsDouble())
  62. {
  63. result.Combine(LoadVariant<float>(*property, 0.0f, inputValue, context));
  64. }
  65. else if (inputValue.IsArray() && inputValue.Size() == 4)
  66. {
  67. result.Combine(LoadVariant<Vector4>(*property, Vector4{0.0f, 0.0f, 0.0f, 0.0f}, inputValue, context));
  68. }
  69. else if (inputValue.IsArray() && inputValue.Size() == 3)
  70. {
  71. result.Combine(LoadVariant<Vector3>(*property, Vector3{0.0f, 0.0f, 0.0f}, inputValue, context));
  72. }
  73. else if (inputValue.IsArray() && inputValue.Size() == 2)
  74. {
  75. result.Combine(LoadVariant<Vector2>(*property, Vector2{0.0f, 0.0f}, inputValue, context));
  76. }
  77. else if (inputValue.IsObject())
  78. {
  79. JsonSerializationResult::ResultCode resultCode = LoadVariant<Color>(*property, Color::CreateZero(), inputValue, context);
  80. if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed)
  81. {
  82. resultCode = LoadVariant<Vector4>(*property, Vector4::CreateZero(), inputValue, context);
  83. }
  84. if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed)
  85. {
  86. resultCode = LoadVariant<Vector3>(*property, Vector3::CreateZero(), inputValue, context);
  87. }
  88. if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed)
  89. {
  90. resultCode = LoadVariant<Vector2>(*property, Vector2::CreateZero(), inputValue, context);
  91. }
  92. if(resultCode.GetProcessing() == JsonSerializationResult::Processing::Completed)
  93. {
  94. result.Combine(resultCode);
  95. }
  96. else
  97. {
  98. return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Unsupported, "Unknown data type");
  99. }
  100. }
  101. else if (inputValue.IsString())
  102. {
  103. result.Combine(LoadVariant<AZStd::string>(*property, AZStd::string{}, inputValue, context));
  104. }
  105. else
  106. {
  107. return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Unsupported, "Unknown data type");
  108. }
  109. if (result.GetProcessing() == JsonSerializationResult::Processing::Completed)
  110. {
  111. return context.Report(result, "Successfully loaded property value.");
  112. }
  113. else
  114. {
  115. return context.Report(result, "Partially loaded property value.");
  116. }
  117. }
  118. JsonSerializationResult::Result JsonMaterialPropertyValueSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
  119. [[maybe_unused]] const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context)
  120. {
  121. namespace JSR = JsonSerializationResult;
  122. AZ_Assert(azrtti_typeid<MaterialPropertyValue>() == valueTypeId,
  123. "Unable to serialize material property value to json because the provided type is %s",
  124. valueTypeId.ToString<AZStd::string>().c_str());
  125. AZ_UNUSED(valueTypeId);
  126. const MaterialPropertyValue* property = reinterpret_cast<const MaterialPropertyValue*>(inputValue);
  127. AZ_Assert(property, "Input value for JsonMaterialPropertyValueSerializer can't be null.");
  128. JSR::ResultCode result(JSR::Tasks::WriteValue);
  129. if (property->Is<bool>())
  130. {
  131. result.Combine(ContinueStoring(outputValue, &property->GetValue<bool>(), nullptr, azrtti_typeid<bool>(), context));
  132. }
  133. else if (property->Is<int32_t>())
  134. {
  135. result.Combine(ContinueStoring(outputValue, &property->GetValue<int32_t>(), nullptr, azrtti_typeid<int32_t>(), context));
  136. }
  137. else if (property->Is<uint32_t>())
  138. {
  139. result.Combine(ContinueStoring(outputValue, &property->GetValue<uint32_t>(), nullptr, azrtti_typeid<uint32_t>(), context));
  140. }
  141. else if (property->Is<float>())
  142. {
  143. result.Combine(ContinueStoring(outputValue, &property->GetValue<float>(), nullptr, azrtti_typeid<float>(), context));
  144. }
  145. else if (property->Is<Vector2>())
  146. {
  147. result.Combine(ContinueStoring(outputValue, &property->GetValue<Vector2>(), nullptr, azrtti_typeid<Vector2>(), context));
  148. }
  149. else if (property->Is<Vector3>())
  150. {
  151. result.Combine(ContinueStoring(outputValue, &property->GetValue<Vector3>(), nullptr, azrtti_typeid<Vector3>(), context));
  152. }
  153. else if (property->Is<Vector4>())
  154. {
  155. result.Combine(ContinueStoring(outputValue, &property->GetValue<Vector4>(), nullptr, azrtti_typeid<Vector4>(), context));
  156. }
  157. else if (property->Is<Color>())
  158. {
  159. result.Combine(ContinueStoring(outputValue, &property->GetValue<Color>(), nullptr, azrtti_typeid<Color>(), context));
  160. }
  161. else if (property->Is<AZStd::string>())
  162. {
  163. result.Combine(ContinueStoring(outputValue, &property->GetValue<AZStd::string>(), nullptr, azrtti_typeid<AZStd::string>(), context));
  164. }
  165. else
  166. {
  167. result.Combine(context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Unsupported,
  168. AZStd::string::format("MaterialPropertyValue type %s is not supported.", property->GetTypeId().ToString<AZStd::string>().c_str())));
  169. }
  170. if (result.GetProcessing() == JsonSerializationResult::Processing::Completed)
  171. {
  172. return context.Report(result, "Successfully stored property value.");
  173. }
  174. else
  175. {
  176. return context.Report(result, "Partially stored property value.");
  177. }
  178. }
  179. } // namespace RPI
  180. } // namespace AZ