Merge pull request #7123 from aws-lumberyard-dev/cgalvan/gitflow_220124_o3de_development

Merged `stabilization/2111RTE` to `development`
monroegm-disable-blank-issue-2
Chris Galvan 4 years ago committed by GitHub
commit a2db9806a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -198,9 +198,7 @@ namespace O3DE::ProjectManager
return true; return true;
} }
bool forceRegistration = false; // check if an engine with this name is already registered and has a valid engine.json
// check if an engine with this name is already registered
auto existingEngineResult = m_pythonBindings->GetEngineInfo(engineInfo.m_name); auto existingEngineResult = m_pythonBindings->GetEngineInfo(engineInfo.m_name);
if (existingEngineResult) if (existingEngineResult)
{ {
@ -232,10 +230,11 @@ namespace O3DE::ProjectManager
// user elected not to change the name or force registration // user elected not to change the name or force registration
return false; return false;
} }
forceRegistration = true;
} }
// always force register in case there is an engine registered in o3de_manifest.json, but
// the engine.json is missing or corrupt in which case GetEngineInfo() fails
constexpr bool forceRegistration = true;
auto registerOutcome = m_pythonBindings->SetEngineInfo(engineInfo, forceRegistration); auto registerOutcome = m_pythonBindings->SetEngineInfo(engineInfo, forceRegistration);
if (!registerOutcome) if (!registerOutcome)
{ {

@ -459,6 +459,9 @@ namespace O3DE::ProjectManager
if (!pybind11::isinstance<pybind11::none>(enginePathResult)) if (!pybind11::isinstance<pybind11::none>(enginePathResult))
{ {
engineInfo = EngineInfoFromPath(enginePathResult); engineInfo = EngineInfoFromPath(enginePathResult);
// it is possible an engine is registered in o3de_manifest.json but the engine.json is
// missing or corrupt in which case we do not consider it a registered engine
} }
}); });

@ -16,7 +16,9 @@ namespace AZ
AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialAssignmentSerializer, AZ::SystemAllocator, 0); AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialAssignmentSerializer, AZ::SystemAllocator, 0);
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Load( JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Load(
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, void* outputValue,
[[maybe_unused]] const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue,
JsonDeserializerContext& context) JsonDeserializerContext& context)
{ {
namespace JSR = JsonSerializationResult; namespace JSR = JsonSerializationResult;
@ -62,6 +64,7 @@ namespace AZ
LoadAny<AZ::Color>(propertyValue, inputPropertyPair.value, context, result) || LoadAny<AZ::Color>(propertyValue, inputPropertyPair.value, context, result) ||
LoadAny<AZStd::string>(propertyValue, inputPropertyPair.value, context, result) || LoadAny<AZStd::string>(propertyValue, inputPropertyPair.value, context, result) ||
LoadAny<AZ::Data::AssetId>(propertyValue, inputPropertyPair.value, context, result) || LoadAny<AZ::Data::AssetId>(propertyValue, inputPropertyPair.value, context, result) ||
LoadAny<AZ::Data::Asset<AZ::Data::AssetData>>(propertyValue, inputPropertyPair.value, context, result) ||
LoadAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, inputPropertyPair.value, context, result) || LoadAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, inputPropertyPair.value, context, result) ||
LoadAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, inputPropertyPair.value, context, result)) LoadAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, inputPropertyPair.value, context, result))
{ {
@ -78,7 +81,10 @@ namespace AZ
} }
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Store( JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId, rapidjson::Value& outputValue,
const void* inputValue,
const void* defaultValue,
[[maybe_unused]] const Uuid& valueTypeId,
JsonSerializerContext& context) JsonSerializerContext& context)
{ {
namespace JSR = AZ::JsonSerializationResult; namespace JSR = AZ::JsonSerializationResult;
@ -138,9 +144,9 @@ namespace AZ
StoreAny<AZ::Color>(propertyValue, outputPropertyValue, context, result) || StoreAny<AZ::Color>(propertyValue, outputPropertyValue, context, result) ||
StoreAny<AZStd::string>(propertyValue, outputPropertyValue, context, result) || StoreAny<AZStd::string>(propertyValue, outputPropertyValue, context, result) ||
StoreAny<AZ::Data::AssetId>(propertyValue, outputPropertyValue, context, result) || StoreAny<AZ::Data::AssetId>(propertyValue, outputPropertyValue, context, result) ||
StoreAny<AZ::Data::Asset<AZ::Data::AssetData>>(propertyValue, outputPropertyValue, context, result) ||
StoreAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, outputPropertyValue, context, result) || StoreAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, outputPropertyValue, context, result) ||
StoreAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>( StoreAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, outputPropertyValue, context, result))
propertyValue, outputPropertyValue, context, result))
{ {
outputPropertyValueContainer.AddMember( outputPropertyValueContainer.AddMember(
rapidjson::Value::StringRefType(propertyName.GetCStr()), outputPropertyValue, rapidjson::Value::StringRefType(propertyName.GetCStr()), outputPropertyValue,
@ -164,7 +170,9 @@ namespace AZ
template<typename T> template<typename T>
bool JsonMaterialAssignmentSerializer::LoadAny( bool JsonMaterialAssignmentSerializer::LoadAny(
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context, AZStd::any& propertyValue,
const rapidjson::Value& inputPropertyValue,
AZ::JsonDeserializerContext& context,
AZ::JsonSerializationResult::ResultCode& result) AZ::JsonSerializationResult::ResultCode& result)
{ {
if (inputPropertyValue.IsObject() && inputPropertyValue.HasMember("Value") && inputPropertyValue.HasMember("$type")) if (inputPropertyValue.IsObject() && inputPropertyValue.HasMember("Value") && inputPropertyValue.HasMember("$type"))
@ -187,7 +195,9 @@ namespace AZ
template<typename T> template<typename T>
bool JsonMaterialAssignmentSerializer::StoreAny( bool JsonMaterialAssignmentSerializer::StoreAny(
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context, const AZStd::any& propertyValue,
rapidjson::Value& outputPropertyValue,
AZ::JsonSerializerContext& context,
AZ::JsonSerializationResult::ResultCode& result) AZ::JsonSerializationResult::ResultCode& result)
{ {
if (propertyValue.is<T>()) if (propertyValue.is<T>())
@ -199,7 +209,7 @@ namespace AZ
result.Combine(StoreTypeId(typeValue, azrtti_typeid<T>(), context)); result.Combine(StoreTypeId(typeValue, azrtti_typeid<T>(), context));
outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator()); outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator());
T value = AZStd::any_cast<T>(propertyValue); const T& value = AZStd::any_cast<T>(propertyValue);
result.Combine( result.Combine(
ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid<T>(), context)); ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid<T>(), context));
return true; return true;

@ -25,21 +25,31 @@ namespace AZ
AZ_CLASS_ALLOCATOR_DECL; AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load( JsonSerializationResult::Result Load(
void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, void* outputValue,
const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override; JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store( JsonSerializationResult::Result Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, rapidjson::Value& outputValue,
const void* inputValue,
const void* defaultValue,
const Uuid& valueTypeId,
JsonSerializerContext& context) override; JsonSerializerContext& context) override;
private: private:
template<typename T> template<typename T>
bool LoadAny( bool LoadAny(
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context, AZStd::any& propertyValue,
const rapidjson::Value& inputPropertyValue,
AZ::JsonDeserializerContext& context,
AZ::JsonSerializationResult::ResultCode& result); AZ::JsonSerializationResult::ResultCode& result);
template<typename T> template<typename T>
bool StoreAny( bool StoreAny(
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context, const AZStd::any& propertyValue,
rapidjson::Value& outputPropertyValue,
AZ::JsonSerializerContext& context,
AZ::JsonSerializationResult::ResultCode& result); AZ::JsonSerializationResult::ResultCode& result);
}; };
} // namespace Render } // namespace Render

@ -33,11 +33,13 @@ namespace AtomToolsFramework
{ {
if (value.Is<AZ::Data::Asset<AZ::RPI::ImageAsset>>()) if (value.Is<AZ::Data::Asset<AZ::RPI::ImageAsset>>())
{ {
const AZ::Data::Asset<AZ::RPI::ImageAsset>& imageAsset = value.GetValue<AZ::Data::Asset<AZ::RPI::ImageAsset>>(); const auto& imageAsset = value.GetValue<AZ::Data::Asset<AZ::RPI::ImageAsset>>();
return AZStd::any(AZ::Data::Asset<AZ::RPI::StreamingImageAsset>( return AZStd::any(AZ::Data::Asset<AZ::RPI::StreamingImageAsset>(imageAsset.GetId(), azrtti_typeid<AZ::RPI::StreamingImageAsset>(), imageAsset.GetHint()));
imageAsset.GetId(), }
azrtti_typeid<AZ::RPI::StreamingImageAsset>(), else if (value.Is<AZ::Data::Instance<AZ::RPI::Image>>())
imageAsset.GetHint())); {
const auto& image = value.GetValue<AZ::Data::Instance<AZ::RPI::Image>>();
return AZStd::any(AZ::Data::Asset<AZ::RPI::StreamingImageAsset>(image->GetAssetId(), azrtti_typeid<AZ::RPI::StreamingImageAsset>()));
} }
return AZ::RPI::MaterialPropertyValue::ToAny(value); return AZ::RPI::MaterialPropertyValue::ToAny(value);

@ -104,6 +104,7 @@ namespace AZ
MaterialComponentController::MaterialComponentController(const MaterialComponentConfig& config) MaterialComponentController::MaterialComponentController(const MaterialComponentConfig& config)
: m_configuration(config) : m_configuration(config)
{ {
ConvertAssetsForSerialization();
} }
void MaterialComponentController::Activate(EntityId entityId) void MaterialComponentController::Activate(EntityId entityId)
@ -135,6 +136,7 @@ namespace AZ
void MaterialComponentController::SetConfiguration(const MaterialComponentConfig& config) void MaterialComponentController::SetConfiguration(const MaterialComponentConfig& config)
{ {
m_configuration = config; m_configuration = config;
ConvertAssetsForSerialization();
} }
const MaterialComponentConfig& MaterialComponentController::GetConfiguration() const const MaterialComponentConfig& MaterialComponentController::GetConfiguration() const
@ -338,6 +340,7 @@ namespace AZ
// before LoadMaterials() is called [LYN-2249] // before LoadMaterials() is called [LYN-2249]
auto temp = m_configuration.m_materials; auto temp = m_configuration.m_materials;
m_configuration.m_materials = materials; m_configuration.m_materials = materials;
ConvertAssetsForSerialization();
LoadMaterials(); LoadMaterials();
} }
@ -489,6 +492,7 @@ namespace AZ
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId]; auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty(); const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value; materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value;
ConvertAssetsForSerialization();
if (materialAssignment.RequiresLoading()) if (materialAssignment.RequiresLoading())
{ {
@ -586,6 +590,7 @@ namespace AZ
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId]; auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty(); const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
materialAssignment.m_propertyOverrides = propertyOverrides; materialAssignment.m_propertyOverrides = propertyOverrides;
ConvertAssetsForSerialization();
if (materialAssignment.RequiresLoading()) if (materialAssignment.RequiresLoading())
{ {
@ -667,5 +672,33 @@ namespace AZ
TickBus::Handler::BusConnect(); TickBus::Handler::BusConnect();
} }
} }
void MaterialComponentController::ConvertAssetsForSerialization()
{
for (auto& materialAssignmentPair : m_configuration.m_materials)
{
MaterialAssignment& materialAssignment = materialAssignmentPair.second;
for (auto& propertyPair : materialAssignment.m_propertyOverrides)
{
auto& value = propertyPair.second;
if (value.is<AZ::Data::Asset<AZ::Data::AssetData>>())
{
value = AZStd::any_cast<AZ::Data::Asset<AZ::Data::AssetData>>(value).GetId();
}
else if (value.is<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>())
{
value = AZStd::any_cast<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(value).GetId();
}
else if (value.is<AZ::Data::Asset<AZ::RPI::ImageAsset>>())
{
value = AZStd::any_cast<AZ::Data::Asset<AZ::RPI::ImageAsset>>(value).GetId();
}
else if (value.is<AZ::Data::Instance<AZ::RPI::Image>>())
{
value = AZStd::any_cast<AZ::Data::Instance<AZ::RPI::Image>>(value)->GetAssetId();
}
}
}
}
} // namespace Render } // namespace Render
} // namespace AZ } // namespace AZ

@ -99,6 +99,11 @@ namespace AZ
//! Queue material instance recreation notifiucations until tick //! Queue material instance recreation notifiucations until tick
void QueueMaterialUpdateNotification(); void QueueMaterialUpdateNotification();
//! Converts property overrides storing image asset references into asset IDs. This addresses a problem where image property
//! overrides are lost during prefab serialization and patching. This suboptimal function will be removed once the underlying
//! problem is resolved.
void ConvertAssetsForSerialization();
EntityId m_entityId; EntityId m_entityId;
MaterialComponentConfig m_configuration; MaterialComponentConfig m_configuration;
AZStd::unordered_set<MaterialAssignmentId> m_materialsWithDirtyProperties; AZStd::unordered_set<MaterialAssignmentId> m_materialsWithDirtyProperties;

@ -644,7 +644,7 @@ def get_registered(engine_name: str = None,
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
logger.warning(f'{engine_json} failed to load: {str(e)}') logger.warning(f'{engine_json} failed to load: {str(e)}')
else: else:
this_engines_name = engine_json_data['engine_name'] this_engines_name = engine_json_data.get('engine_name','')
if this_engines_name == engine_name: if this_engines_name == engine_name:
return engine_path return engine_path
engines_path = json_data.get('engines_path', {}) engines_path = json_data.get('engines_path', {})
@ -656,60 +656,72 @@ def get_registered(engine_name: str = None,
for project_path in projects: for project_path in projects:
project_path = pathlib.Path(project_path).resolve() project_path = pathlib.Path(project_path).resolve()
project_json = project_path / 'project.json' project_json = project_path / 'project.json'
with project_json.open('r') as f: if not pathlib.Path(project_json).is_file():
try: logger.warning(f'{project_json} does not exist')
project_json_data = json.load(f) else:
except json.JSONDecodeError as e: with project_json.open('r') as f:
logger.warning(f'{project_json} failed to load: {str(e)}') try:
else: project_json_data = json.load(f)
this_projects_name = project_json_data['project_name'] except json.JSONDecodeError as e:
if this_projects_name == project_name: logger.warning(f'{project_json} failed to load: {str(e)}')
return project_path else:
this_projects_name = project_json_data['project_name']
if this_projects_name == project_name:
return project_path
elif isinstance(gem_name, str): elif isinstance(gem_name, str):
gems = get_all_gems(project_path) gems = get_all_gems(project_path)
for gem_path in gems: for gem_path in gems:
gem_path = pathlib.Path(gem_path).resolve() gem_path = pathlib.Path(gem_path).resolve()
gem_json = gem_path / 'gem.json' gem_json = gem_path / 'gem.json'
with gem_json.open('r') as f: if not pathlib.Path(gem_json).is_file():
try: logger.warning(f'{gem_json} does not exist')
gem_json_data = json.load(f) else:
except json.JSONDecodeError as e: with gem_json.open('r') as f:
logger.warning(f'{gem_json} failed to load: {str(e)}') try:
else: gem_json_data = json.load(f)
this_gems_name = gem_json_data['gem_name'] except json.JSONDecodeError as e:
if this_gems_name == gem_name: logger.warning(f'{gem_json} failed to load: {str(e)}')
return gem_path else:
this_gems_name = gem_json_data['gem_name']
if this_gems_name == gem_name:
return gem_path
elif isinstance(template_name, str): elif isinstance(template_name, str):
templates = get_all_templates(project_path) templates = get_all_templates(project_path)
for template_path in templates: for template_path in templates:
template_path = pathlib.Path(template_path).resolve() template_path = pathlib.Path(template_path).resolve()
template_json = template_path / 'template.json' template_json = template_path / 'template.json'
with template_json.open('r') as f: if not pathlib.Path(template_json).is_file():
try: logger.warning(f'{template_json} does not exist')
template_json_data = json.load(f) else:
except json.JSONDecodeError as e: with template_json.open('r') as f:
logger.warning(f'{template_path} failed to load: {str(e)}') try:
else: template_json_data = json.load(f)
this_templates_name = template_json_data['template_name'] except json.JSONDecodeError as e:
if this_templates_name == template_name: logger.warning(f'{template_path} failed to load: {str(e)}')
return template_path else:
this_templates_name = template_json_data['template_name']
if this_templates_name == template_name:
return template_path
elif isinstance(restricted_name, str): elif isinstance(restricted_name, str):
restricted = get_manifest_restricted() restricted = get_manifest_restricted()
for restricted_path in restricted: for restricted_path in restricted:
restricted_path = pathlib.Path(restricted_path).resolve() restricted_path = pathlib.Path(restricted_path).resolve()
restricted_json = restricted_path / 'restricted.json' restricted_json = restricted_path / 'restricted.json'
with restricted_json.open('r') as f: if not pathlib.Path(restricted_json).is_file():
try: logger.warning(f'{restricted_json} does not exist')
restricted_json_data = json.load(f) else:
except json.JSONDecodeError as e: with restricted_json.open('r') as f:
logger.warning(f'{restricted_json} failed to load: {str(e)}') try:
else: restricted_json_data = json.load(f)
this_restricted_name = restricted_json_data['restricted_name'] except json.JSONDecodeError as e:
if this_restricted_name == restricted_name: logger.warning(f'{restricted_json} failed to load: {str(e)}')
return restricted_path else:
this_restricted_name = restricted_json_data['restricted_name']
if this_restricted_name == restricted_name:
return restricted_path
elif isinstance(default_folder, str): elif isinstance(default_folder, str):
if default_folder == 'engines': if default_folder == 'engines':

Loading…
Cancel
Save