[LYN-3717] When pulling in an actor FBX, two entities are spawned & [ATOM-15258] Clicking and Dragging fbx file into viewport produces 2 entities (#1392)

* [LYN-3717] When pulling in an actor FBX, two entities are spawned & [ATOM-15258] Clicking and Dragging fbx file into viewport produces 2 entities
* Added another operation to the CanSpawnEntityForProduct that checks the other products and can veto the creation process.
* The model product will not create an entity in case there is already an actor exported, which prevents the issue reported by two different teams/users.
This commit is contained in:
Benjamin Jillich
2021-06-22 05:12:42 -07:00
committed by GitHub
parent 858dee2210
commit 7d5a7b47ac
4 changed files with 57 additions and 10 deletions
@@ -57,7 +57,13 @@ namespace AZ
//! Determines if a component can be created from the asset type
//! This will be called before attempting to create a component from an asset (drag&drop, etc)
//! You can use this to filter by subIds or do your own validation here if needed
virtual bool CanCreateComponent(const AZ::Data::AssetId& /*assetId*/) const { return true; }
virtual bool CanCreateComponent([[maybe_unused]] const AZ::Data::AssetId& assetId) const { return true; }
//! Determines if other products conflict with the given one when multiple are generated from a source asset.
//! This will be called before attempting to create a component from an asset (drag&drop, etc)
//! You can use this to filter by conflicting product types or in case you want to skip for UX reasons.
//! @param[in] productAssetTypes Asset types of all generated products, including the one for our given type in this bus.
virtual bool HasConflictingProducts([[maybe_unused]] const AZStd::vector<AZ::Data::AssetType>& productAssetTypes) const { return false; }
};
using AssetTypeInfoBus = AZ::EBus<AssetTypeInfo>;
@@ -56,7 +56,8 @@ namespace AzAssetBrowserRequestHandlerPrivate
using namespace AzToolsFramework;
using namespace AzToolsFramework::AssetBrowser;
// return true ONLY if we can handle the drop request in the viewport.
bool CanSpawnEntityForProduct(const ProductAssetBrowserEntry* product)
bool CanSpawnEntityForProduct(const ProductAssetBrowserEntry* product,
AZStd::optional<const AZStd::vector<AZ::Data::AssetType>> optionalProductAssetTypes = AZStd::nullopt)
{
if (!product)
{
@@ -70,7 +71,6 @@ namespace AzAssetBrowserRequestHandlerPrivate
bool canCreateComponent = false;
AZ::AssetTypeInfoBus::EventResult(canCreateComponent, product->GetAssetType(), &AZ::AssetTypeInfo::CanCreateComponent, product->GetAssetId());
if (!canCreateComponent)
{
return false;
@@ -78,16 +78,25 @@ namespace AzAssetBrowserRequestHandlerPrivate
AZ::Uuid componentTypeId = AZ::Uuid::CreateNull();
AZ::AssetTypeInfoBus::EventResult(componentTypeId, product->GetAssetType(), &AZ::AssetTypeInfo::GetComponentTypeId);
if (!componentTypeId.IsNull())
if (componentTypeId.IsNull())
{
// we have a component type that handles this asset.
return true;
return false;
}
if (optionalProductAssetTypes.has_value())
{
bool hasConflictingProducts = false;
AZ::AssetTypeInfoBus::EventResult(hasConflictingProducts, product->GetAssetType(), &AZ::AssetTypeInfo::HasConflictingProducts, optionalProductAssetTypes.value());
if (hasConflictingProducts)
{
return false;
}
}
// additional operations can be added here.
return false;
return true;
}
void SpawnEntityAtPoint(const ProductAssetBrowserEntry* product, AzQtComponents::ViewportDragContext* viewportDragContext, EntityIdList& spawnList, AzFramework::SliceInstantiationTicket& spawnTicket)
@@ -511,9 +520,16 @@ void AzAssetBrowserRequestHandler::Drop(QDropEvent* event, AzQtComponents::DragA
}
// Handle products
AZStd::vector<AZ::Data::AssetType> productAssetTypes;
productAssetTypes.reserve(products.size());
for (const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* entry : products)
{
productAssetTypes.emplace_back(entry->GetAssetType());
}
for (const ProductAssetBrowserEntry* product : products)
{
if (CanSpawnEntityForProduct(product))
if (CanSpawnEntityForProduct(product, productAssetTypes))
{
SpawnEntityAtPoint(product, viewportDragContext, spawnedEntities, spawnTicket);
}
@@ -103,10 +103,14 @@ namespace AZ
AZStd::size_t CalculateTriangleCount() const;
};
class ModelAssetHandler : public AssetHandler<ModelAsset>
class ModelAssetHandler
: public AssetHandler<ModelAsset>
{
public:
AZ_RTTI(ModelAssetHandler, "{993B8CE3-1BBF-4712-84A0-285DB9AE808F}", AssetHandler<ModelAsset>);
// AZ::AssetTypeInfoBus::Handler overrides
bool HasConflictingProducts(const AZStd::vector<AZ::Data::AssetType>& productAssetTypes) const override;
};
} //namespace RPI
} // namespace AZ
@@ -315,5 +315,26 @@ namespace AZ
return modelTriangleCount;
}
} //namespace RPI
bool ModelAssetHandler::HasConflictingProducts(const AZStd::vector<AZ::Data::AssetType>& productAssetTypes) const
{
size_t modelAssetCount = 0;
size_t actorAssetCount = 0;
for (const AZ::Data::AssetType& assetType : productAssetTypes)
{
if (assetType == azrtti_typeid<ModelAsset>())
{
modelAssetCount++;
}
else if (assetType == AZ::Data::AssetType("{F67CC648-EA51-464C-9F5D-4A9CE41A7F86}")) // ActorAsset
{
actorAssetCount++;
}
}
// When dropping a well-defined character, consisting of a mesh and a skeleton/actor,
// do not create an entity with a mesh component.
return modelAssetCount == 1 && actorAssetCount == 1;
}
} // namespace RPI
} // namespace AZ