merge stabilization/2106 into development
Signed-off-by: hultonha <hultonha@amazon.co.uk>
This commit is contained in:
@@ -536,22 +536,19 @@ AZ::Vector2 CDraw2d::Align(AZ::Vector2 position, AZ::Vector2 size,
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
AZ::Data::Instance<AZ::RPI::Image> CDraw2d::LoadTexture(const AZStd::string& pathName)
|
||||
{
|
||||
AZStd::string sourceRelativePath(pathName);
|
||||
AZStd::string cacheRelativePath = sourceRelativePath + ".streamingimage";
|
||||
|
||||
// The file may not be in the AssetCatalog at this point if it is still processing or doesn't exist on disk.
|
||||
// Use GenerateAssetIdTEMP instead of GetAssetIdByPath so that it will return a valid AssetId anyways
|
||||
AZ::Data::AssetId streamingImageAssetId;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
streamingImageAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GenerateAssetIdTEMP,
|
||||
sourceRelativePath.c_str());
|
||||
pathName.c_str());
|
||||
streamingImageAssetId.m_subId = AZ::RPI::StreamingImageAsset::GetImageAssetSubId();
|
||||
|
||||
auto streamingImageAsset = AZ::Data::AssetManager::Instance().FindOrCreateAsset<AZ::RPI::StreamingImageAsset>(streamingImageAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
AZ::Data::Instance<AZ::RPI::Image> image = AZ::RPI::StreamingImage::FindOrCreate(streamingImageAsset);
|
||||
if (!image)
|
||||
{
|
||||
AZ_Error("Draw2d", false, "Failed to find or create an image instance from image asset '%s'", streamingImageAsset.GetHint().c_str());
|
||||
AZ_Error("Draw2d", false, "Failed to find or create an image instance from image asset '%s'", pathName.c_str());
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace LyShine
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
LyShineSystemComponent::LyShineSystemComponent()
|
||||
{
|
||||
m_cursorImagePathname.SetAssetPath("engineassets/textures/cursor_green.tif");
|
||||
m_cursorImagePathname.SetAssetPath("Textures/Cursor_Default.tif");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -590,174 +590,6 @@ bool UiCanvasComponent::SaveToXml(const string& assetIdPathname, const string& s
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
UiCanvasInterface::ErrorCode UiCanvasComponent::CheckElementValidToSaveAsPrefab(AZ::Entity* entity)
|
||||
{
|
||||
AZ_Assert(entity, "null entity ptr passed to SaveAsPrefab");
|
||||
|
||||
// Check that none of the EntityId's in this entity or its children reference entities that
|
||||
// are not part of the prefab.
|
||||
// First make a list of all entityIds that will be in the prefab
|
||||
AZStd::vector<AZ::EntityId> entitiesInPrefab = GetEntityIdsOfElementAndDescendants(entity);
|
||||
|
||||
// Next check all entity refs in the element to see if any are externel
|
||||
// We use ReplaceEntityRefs even though we don't want to change anything
|
||||
bool foundRefOutsidePrefab = false;
|
||||
AZ::SerializeContext* context = nullptr;
|
||||
EBUS_EVENT_RESULT(context, AZ::ComponentApplicationBus, GetSerializeContext);
|
||||
AZ_Assert(context, "No serialization context found");
|
||||
AZ::EntityUtils::ReplaceEntityRefs(entity, [&](const AZ::EntityId& key, bool /*isEntityId*/) -> AZ::EntityId
|
||||
{
|
||||
if (key.IsValid())
|
||||
{
|
||||
auto iter = AZStd::find(entitiesInPrefab.begin(), entitiesInPrefab.end(), key);
|
||||
if (iter == entitiesInPrefab.end())
|
||||
{
|
||||
foundRefOutsidePrefab = true;
|
||||
}
|
||||
}
|
||||
return key; // always leave key unchanged
|
||||
}, context);
|
||||
|
||||
if (foundRefOutsidePrefab)
|
||||
{
|
||||
return UiCanvasInterface::ErrorCode::PrefabContainsExternalEntityRefs;
|
||||
}
|
||||
|
||||
return UiCanvasInterface::ErrorCode::NoError;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool UiCanvasComponent::SaveAsPrefab(const string& pathname, AZ::Entity* entity)
|
||||
{
|
||||
AZ_Assert(entity, "null entity ptr passed to SaveAsPrefab");
|
||||
|
||||
AZ::SerializeContext* context = nullptr;
|
||||
EBUS_EVENT_RESULT(context, AZ::ComponentApplicationBus, GetSerializeContext);
|
||||
AZ_Assert(context, "No serialization context found");
|
||||
|
||||
// To be sure that we do not save an invalid prefab, if this entity contains entity references
|
||||
// outside of the prefab set them to invalid references
|
||||
// First make a list of all entityIds that will be in the prefab
|
||||
AZStd::vector<AZ::EntityId> entitiesInPrefab = GetEntityIdsOfElementAndDescendants(entity);
|
||||
|
||||
// Next make a serializable object containing all the entities to save (in order to check for invalid refs)
|
||||
AZ::SliceComponent::InstantiatedContainer sourceObjects(false);
|
||||
for (const AZ::EntityId& id : entitiesInPrefab)
|
||||
{
|
||||
AZ::Entity* sourceEntity = nullptr;
|
||||
EBUS_EVENT_RESULT(sourceEntity, AZ::ComponentApplicationBus, FindEntity, id);
|
||||
if (sourceEntity)
|
||||
{
|
||||
sourceObjects.m_entities.push_back(sourceEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// clone all the objects in order to replace external references
|
||||
AZ::SliceComponent::InstantiatedContainer* clonedObjects = context->CloneObject(&sourceObjects);
|
||||
AZ::Entity* clonedRootEntity = clonedObjects->m_entities[0];
|
||||
|
||||
// use ReplaceEntityRefs to replace external references with invalid IDs
|
||||
// Note that we are not generating new IDs so we do not need to fixup internal references
|
||||
AZ::EntityUtils::ReplaceEntityRefs(clonedObjects, [&](const AZ::EntityId& key, bool /*isEntityId*/) -> AZ::EntityId
|
||||
{
|
||||
if (key.IsValid())
|
||||
{
|
||||
auto iter = AZStd::find(entitiesInPrefab.begin(), entitiesInPrefab.end(), key);
|
||||
if (iter == entitiesInPrefab.end())
|
||||
{
|
||||
return AZ::EntityId();
|
||||
}
|
||||
}
|
||||
return key; // leave key unchanged
|
||||
}, context);
|
||||
|
||||
// make a wrapper object around the prefab entity so that we have an opportunity to change what
|
||||
// is in a prefab file in future.
|
||||
UiSerialize::PrefabFileObject fileObject;
|
||||
fileObject.m_rootEntityId = clonedRootEntity->GetId();
|
||||
|
||||
// add all of the entities that are not the root entity to a childEntities list
|
||||
for (auto descendant : clonedObjects->m_entities)
|
||||
{
|
||||
fileObject.m_entities.push_back(descendant);
|
||||
}
|
||||
|
||||
bool result = AZ::Utils::SaveObjectToFile(pathname.c_str(), AZ::ObjectStream::ST_XML, &fileObject);
|
||||
|
||||
// now delete the cloned entities we created, fixed up and saved
|
||||
delete clonedObjects;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
AZ::Entity* UiCanvasComponent::LoadFromPrefab(const string& pathname, bool makeUniqueName, AZ::Entity* optionalInsertionPoint)
|
||||
{
|
||||
AZ::Entity* newEntity = nullptr;
|
||||
|
||||
// Currently LoadObjectFromFile will hang if the file cannot be parsed
|
||||
// (LMBR-10078). So first check that it is in the right format
|
||||
if (!IsValidAzSerializedFile(pathname))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The top level object in the file is a wrapper object called PrefabFileObject
|
||||
// this is to give us more protection against changes to what we store in the file in future
|
||||
// NOTE: this read doesn't support pak files but that is OK because prefab files are an
|
||||
// editor only feature.
|
||||
UiSerialize::PrefabFileObject* fileObject =
|
||||
AZ::Utils::LoadObjectFromFile<UiSerialize::PrefabFileObject>(pathname.c_str());
|
||||
AZ_Assert(fileObject, "Failed to load prefab");
|
||||
|
||||
if (fileObject)
|
||||
{
|
||||
// We want new IDs so generate them and fixup all references within the list of entities
|
||||
{
|
||||
AZ::SerializeContext* context = nullptr;
|
||||
EBUS_EVENT_RESULT(context, AZ::ComponentApplicationBus, GetSerializeContext);
|
||||
AZ_Assert(context, "No serialization context found");
|
||||
|
||||
AZ::SliceComponent::EntityIdToEntityIdMap entityIdMap;
|
||||
AZ::IdUtils::Remapper<AZ::EntityId>::GenerateNewIdsAndFixRefs(fileObject, entityIdMap, context);
|
||||
}
|
||||
|
||||
// add all of the entities to this canvases EntityContext
|
||||
m_entityContext->AddUiEntities(fileObject->m_entities);
|
||||
|
||||
EBUS_EVENT_RESULT(newEntity, AZ::ComponentApplicationBus, FindEntity, fileObject->m_rootEntityId);
|
||||
|
||||
delete fileObject; // we do not keep the file wrapper object around
|
||||
|
||||
if (makeUniqueName)
|
||||
{
|
||||
AZ::EntityId parentEntityId;
|
||||
if (optionalInsertionPoint)
|
||||
{
|
||||
parentEntityId = optionalInsertionPoint->GetId();
|
||||
}
|
||||
AZStd::string uniqueName = GetUniqueChildName(parentEntityId, newEntity->GetName(), nullptr);
|
||||
newEntity->SetName(uniqueName);
|
||||
}
|
||||
|
||||
UiElementComponent* elementComponent = newEntity->FindComponent<UiElementComponent>();
|
||||
AZ_Assert(elementComponent, "No element component found on prefab entity");
|
||||
|
||||
AZ::Entity* parent = (optionalInsertionPoint) ? optionalInsertionPoint : GetRootElement();
|
||||
|
||||
// recursively visit all the elements and set their canvas and parent pointers
|
||||
elementComponent->FixupPostLoad(newEntity, this, parent, true);
|
||||
|
||||
// add this new entity as a child of the parent (insertionPoint or root)
|
||||
UiElementComponent* parentElementComponent = parent->FindComponent<UiElementComponent>();
|
||||
AZ_Assert(parentElementComponent, "No element component found on parent entity");
|
||||
parentElementComponent->AddChild(newEntity);
|
||||
}
|
||||
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void UiCanvasComponent::FixupCreatedEntities(LyShine::EntityArray topLevelEntities, bool makeUniqueNamesAndIds, AZ::Entity* optionalInsertionPoint)
|
||||
{
|
||||
@@ -3695,6 +3527,7 @@ void UiCanvasComponent::CreateRenderTarget()
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom
|
||||
// Create a render target that this canvas will be rendered to.
|
||||
// The render target size is the canvas size.
|
||||
m_renderTargetHandle = gEnv->pRenderer->CreateRenderTarget(m_renderTargetName.c_str(),
|
||||
@@ -3716,6 +3549,7 @@ void UiCanvasComponent::CreateRenderTarget()
|
||||
|
||||
ISystem::CrySystemNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -3734,7 +3568,7 @@ void UiCanvasComponent::DestroyRenderTarget()
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void UiCanvasComponent::RenderCanvasToTexture()
|
||||
{
|
||||
#ifdef LYSHINE_ATOM_TODO
|
||||
#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom
|
||||
if (m_renderTargetHandle <= 0)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -99,11 +99,6 @@ public: // member functions
|
||||
AZ::EntityId FindInteractableToHandleEvent(AZ::Vector2 point) override;
|
||||
|
||||
bool SaveToXml(const string& assetIdPathname, const string& sourceAssetPathname) override;
|
||||
bool SaveAsPrefab(const string& pathname, AZ::Entity* entity) override;
|
||||
UiCanvasInterface::ErrorCode CheckElementValidToSaveAsPrefab(AZ::Entity* entity) override;
|
||||
AZ::Entity* LoadFromPrefab(const string& pathname,
|
||||
bool makeUniqueName,
|
||||
AZ::Entity* optionalInsertionPoint) override;
|
||||
void FixupCreatedEntities(LyShine::EntityArray topLevelEntities, bool makeUniqueNamesAndIds, AZ::Entity* optionalInsertionPoint) override;
|
||||
void AddElement(AZ::Entity* element, AZ::Entity* parent, AZ::Entity* insertBefore) override;
|
||||
void ReinitializeElements() override;
|
||||
|
||||
@@ -452,6 +452,7 @@ void UiFaderComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligne
|
||||
m_viewportTopLeft = pixelAlignedTopLeft;
|
||||
m_viewportSize = renderTargetSize;
|
||||
|
||||
#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom
|
||||
// Check if the render target already exists
|
||||
if (m_renderTargetHandle != -1)
|
||||
{
|
||||
@@ -494,6 +495,7 @@ void UiFaderComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligne
|
||||
DestroyRenderTarget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// at this point either all render targets and depth surfaces are created or none are.
|
||||
// If all succeeded then update the render target size
|
||||
@@ -637,6 +639,7 @@ void UiFaderComponent::RenderRttFader(LyShine::IRenderGraph* renderGraph, UiElem
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom
|
||||
// Add a primitive to render a quad using the render target we have created
|
||||
{
|
||||
// Set the texture and other render state required
|
||||
@@ -650,6 +653,7 @@ void UiFaderComponent::RenderRttFader(LyShine::IRenderGraph* renderGraph, UiElem
|
||||
renderGraph->AddPrimitive(&m_cachedPrimitive, texture,
|
||||
isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -553,6 +553,7 @@ void UiMaskComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligned
|
||||
m_viewportTopLeft = pixelAlignedTopLeft;
|
||||
m_viewportSize = renderTargetSize;
|
||||
|
||||
#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom
|
||||
// Check if the render target already exists
|
||||
if (m_contentRenderTargetHandle != -1)
|
||||
{
|
||||
@@ -618,6 +619,7 @@ void UiMaskComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligned
|
||||
DestroyRenderTarget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// at this point either all render targets and depth surfaces are created or none are.
|
||||
// If all succeeded then update the render target size
|
||||
@@ -803,6 +805,7 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom
|
||||
// Add a primitive to do the alpha mask
|
||||
{
|
||||
// Set the texture and other render state required
|
||||
@@ -817,6 +820,7 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph
|
||||
renderGraph->AddAlphaMaskPrimitive(&m_cachedPrimitive, texture, maskTexture,
|
||||
isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -556,11 +556,6 @@ namespace UiSerialize
|
||||
serializeContext->Class<CryStringT<char> >()->
|
||||
Serializer(&AZ::Serialize::StaticInstance<CryStringTCharSerializer>::s_instance);
|
||||
|
||||
serializeContext->Class<PrefabFileObject>()
|
||||
->Version(2, &PrefabFileObject::VersionConverter)
|
||||
->Field("RootEntity", &PrefabFileObject::m_rootEntityId)
|
||||
->Field("Entities", &PrefabFileObject::m_entities);
|
||||
|
||||
serializeContext->Class<AnimationData>()
|
||||
->Version(1)
|
||||
->Field("SerializeString", &AnimationData::m_serializeData);
|
||||
@@ -607,54 +602,6 @@ namespace UiSerialize
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool PrefabFileObject::VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
if (classElement.GetVersion() == 1)
|
||||
{
|
||||
// this is an old UI prefab (prior to UI Slices). We need to move all of the owned child entities into a
|
||||
// separate list and have the references to them be via entity ID
|
||||
|
||||
// Find the m_rootEntity in the PrefabFileObject, in the old format this is an entity,
|
||||
// we will replace it with an entityId
|
||||
int rootEntityIndex = classElement.FindElement(AZ_CRC("RootEntity", 0x3cead042));
|
||||
if (rootEntityIndex == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AZ::SerializeContext::DataElementNode& rootEntityNode = classElement.GetSubElement(rootEntityIndex);
|
||||
|
||||
// All UI element entities will be copied to this container and then added to the m_childEntities list
|
||||
AZStd::vector<AZ::SerializeContext::DataElementNode> copiedEntities;
|
||||
|
||||
// recursively process the root element and all of its child elements, copying their child entities to the
|
||||
// entities container and replacing them with EntityIds
|
||||
if (!UiElementComponent::MoveEntityAndDescendantsToListAndReplaceWithEntityId(context, rootEntityNode, -1, copiedEntities))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the child entities member (which is a generic vector)
|
||||
using entityVector = AZStd::vector<AZ::Entity*>;
|
||||
AZ::SerializeContext::ClassData* classData = AZ::SerializeGenericTypeInfo<entityVector>::GetGenericInfo()->GetClassData();
|
||||
int entitiesIndex = classElement.AddElement(context, "Entities", *classData);
|
||||
if (entitiesIndex == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AZ::SerializeContext::DataElementNode& entitiesNode = classElement.GetSubElement(entitiesIndex);
|
||||
|
||||
// now add all of the copied entities to the entities vector node
|
||||
for (AZ::SerializeContext::DataElementNode& entityElement : copiedEntities)
|
||||
{
|
||||
entityElement.SetName("element"); // all elements in the Vector should have this name
|
||||
entitiesNode.AddElement(entityElement);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper function to VersionConverter to move three state actions from the derived interactable
|
||||
// to the interactable base class
|
||||
|
||||
@@ -16,20 +16,6 @@ namespace UiSerialize
|
||||
//! Define the Cry and UI types for the AZ Serialize system
|
||||
void ReflectUiTypes(AZ::ReflectContext* context);
|
||||
|
||||
//! Wrapper class for prefab file. This allows us to make changes to what the top
|
||||
//! level objects are in the prefab file and do some conversion
|
||||
//! NOTE: This is only used for old pre-slices UI prefabs
|
||||
class PrefabFileObject
|
||||
{
|
||||
public:
|
||||
virtual ~PrefabFileObject() { }
|
||||
AZ_CLASS_ALLOCATOR(PrefabFileObject, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(PrefabFileObject, "{C264CC6F-E50C-4813-AAE6-F7AB0B1774D0}");
|
||||
static bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
|
||||
AZ::EntityId m_rootEntityId;
|
||||
AZStd::vector<AZ::Entity*> m_entities;
|
||||
};
|
||||
|
||||
//! Wrapper class for animation system data file. This allows us to use the old Cry
|
||||
//! serialize for the animation data
|
||||
class AnimationData
|
||||
|
||||
@@ -62,7 +62,7 @@ public: // static member functions
|
||||
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("LegacyMeshService", 0xb462a299));
|
||||
required.push_back(AZ_CRC("MeshService", 0x71d8a455));
|
||||
required.push_back(AZ_CRC("UiCanvasRefService", 0xb4cb5ef4));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user