/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include namespace AZ { namespace RPI { static_assert(( AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v> && AZStd::is_same_v, AZStd::variant_alternative_t<9, MaterialPropertyValue::ValueType>> && AZStd::is_same_v, AZStd::variant_alternative_t<10, MaterialPropertyValue::ValueType>> && AZStd::is_same_v>), "Types must be in the order of the type ID array."); void MaterialPropertyValue::Reflect(ReflectContext* context) { if (auto* serializeContext = azrtti_cast(context)) { serializeContext->RegisterGenericType(); serializeContext->Class() ->Version(1) ->Field("Value", &MaterialPropertyValue::m_value) ; } } TypeId MaterialPropertyValue::GetTypeId() const { // Must sort in the same order defined in the variant. static const AZ::TypeId PropertyValueTypeIds[] = { azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid>(), azrtti_typeid>(), azrtti_typeid(), }; return PropertyValueTypeIds[m_value.index()]; } MaterialPropertyValue MaterialPropertyValue::FromAny(const AZStd::any& value) { MaterialPropertyValue result; if (value.empty()) { return result; } if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = aznumeric_cast(AZStd::any_cast(value)); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else if (value.is()) { auto assetId = AZStd::any_cast(value); AZ::Data::AssetInfo assetInfo; AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId); if (assetInfo.m_assetId.IsValid()) { result.m_value = Data::Asset( assetId, assetInfo.m_assetType, assetInfo.m_relativePath.c_str()); } else { result.m_value = Data::Asset(assetId, azrtti_typeid()); } } else if (value.is>()) { auto asset = AZStd::any_cast>(value); AZ::Data::AssetInfo assetInfo; AZ::Data::AssetCatalogRequestBus::BroadcastResult( assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, asset.GetId()); if (assetInfo.m_assetId.IsValid()) { result.m_value = Data::Asset(assetInfo.m_assetId, assetInfo.m_assetType, assetInfo.m_relativePath); } else { result.m_value = asset; } } else if (value.is>()) { auto asset = AZStd::any_cast>(value); result.m_value = Data::Asset(asset.GetId(), azrtti_typeid(), asset.GetHint()); } else if (value.is>()) { auto asset = AZStd::any_cast>(value); result.m_value = Data::Asset(asset.GetId(), azrtti_typeid(), asset.GetHint()); } else if (value.is>()) { result.m_value = AZStd::any_cast>(value); } else if (value.is>()) { result.m_value = AZStd::any_cast>(value); } else if (value.is()) { result.m_value = AZStd::any_cast(value); } else { AZ_Warning( "MaterialPropertyValue", false, "Cannot convert any to variant. Type in any is: %s.", value.get_type_info().m_id.ToString().data()); } return result; } AZStd::any MaterialPropertyValue::ToAny(const MaterialPropertyValue& value) { AZStd::any result; if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } else if (AZStd::holds_alternative>(value.m_value)) { result = AZStd::get>(value.m_value); } else if (AZStd::holds_alternative>(value.m_value)) { result = AZStd::get>(value.m_value); } else if (AZStd::holds_alternative(value.m_value)) { result = AZStd::get(value.m_value); } return result; } //! Attempts to convert a numeric MaterialPropertyValue to another numeric type @T. //! If the original MaterialPropertyValue is not a numeric type, the original value is returned. template static MaterialPropertyValue CastNumericMaterialPropertyValue(const MaterialPropertyValue& value) { TypeId typeId = value.GetTypeId(); if (typeId == azrtti_typeid()) { return aznumeric_cast(value.GetValue()); } else if (typeId == azrtti_typeid()) { return aznumeric_cast(value.GetValue()); } else if (typeId == azrtti_typeid()) { return aznumeric_cast(value.GetValue()); } else if (typeId == azrtti_typeid()) { return aznumeric_cast(value.GetValue()); } else { return value; } } //! Attempts to convert an AZ::Vector[2-4] MaterialPropertyValue to another AZ::Vector[2-4] type @T. //! Any extra elements will be dropped or set to 0.0 as needed. //! If the original MaterialPropertyValue is not a Vector type, the original value is returned. template static MaterialPropertyValue CastVectorMaterialPropertyValue(const MaterialPropertyValue& value) { float values[4] = {}; TypeId typeId = value.GetTypeId(); if (typeId == azrtti_typeid()) { value.GetValue().StoreToFloat2(values); } else if (typeId == azrtti_typeid()) { value.GetValue().StoreToFloat3(values); } else if (typeId == azrtti_typeid()) { value.GetValue().StoreToFloat4(values); } else { return value; } typeId = azrtti_typeid(); if (typeId == azrtti_typeid()) { return Vector2::CreateFromFloat2(values); } else if (typeId == azrtti_typeid()) { return Vector3::CreateFromFloat3(values); } else if (typeId == azrtti_typeid()) { return Vector4::CreateFromFloat4(values); } else { return value; } } MaterialPropertyValue MaterialPropertyValue::CastToType(TypeId requestedType) const { if (requestedType == azrtti_typeid()) { return CastNumericMaterialPropertyValue(*this); } else if (requestedType == azrtti_typeid()) { return CastNumericMaterialPropertyValue(*this); } else if (requestedType == azrtti_typeid()) { return CastNumericMaterialPropertyValue(*this); } else if (requestedType == azrtti_typeid()) { return CastNumericMaterialPropertyValue(*this); } else if (requestedType == azrtti_typeid()) { return CastVectorMaterialPropertyValue(*this); } else if (requestedType == azrtti_typeid()) { if (GetTypeId() == azrtti_typeid()) { return GetValue().GetAsVector3(); } else { return CastVectorMaterialPropertyValue(*this); } } else if (requestedType == azrtti_typeid()) { if (GetTypeId() == azrtti_typeid()) { return GetValue().GetAsVector4(); } else { return CastVectorMaterialPropertyValue(*this); } } else if (requestedType == azrtti_typeid()) { if (GetTypeId() == azrtti_typeid()) { return Color::CreateFromVector3(GetValue()); } else if (GetTypeId() == azrtti_typeid()) { Vector4 vector4 = GetValue(); return Color::CreateFromVector3AndFloat(vector4.GetAsVector3(), vector4.GetW()); } else { // Don't attempt conversion from e.g. Vector2 as that makes little sense. return *this; } } else { // remaining types are non-numerical and cannot be cast to other types: return as-is return *this; } } } // namespace RPI } // namespace AZ