Cloth works with Actors in Atom. Cloth system uses MeshAssetHelper to read model mesh information for actors too.

This commit is contained in:
moraaar
2021-04-16 18:24:29 +01:00
parent 41eadd60e4
commit 808fd1d3ba
6 changed files with 41 additions and 67 deletions
@@ -212,19 +212,26 @@ namespace AZ
void AtomActorInstance::SetModelAsset([[maybe_unused]] Data::Asset<RPI::ModelAsset> modelAsset)
{
// Atom Actor Instance is not based on an actual Model Asset yet,
// it's created at runtime from an Actor Asset.
// Changing model asset is not supported by Atom Actor Instance.
// The model asset is obtained from the Actor inside the ActorAsset,
// which is passed to the constructor. To set a different model asset
// this instance should use a different Actor.
AZ_Assert(false, "AtomActorInstance::SetModelAsset not supported");
}
const Data::Asset<RPI::ModelAsset>& AtomActorInstance::GetModelAsset() const
{
return m_skinnedMeshInstance->m_model->GetModelAsset();
AZ_Assert(GetActor(), "Expecting a Atom Actor Instance having a valid Actor.");
return GetActor()->GetMeshAsset();
}
void AtomActorInstance::SetModelAssetId([[maybe_unused]] Data::AssetId modelAssetId)
{
// Atom Actor Instance is not based on an actual Model Asset yet,
// it's created at runtime from an Actor Asset.
// Changing model asset is not supported by Atom Actor Instance.
// The model asset is obtained from the Actor inside the ActorAsset,
// which is passed to the constructor. To set a different model asset
// this instance should use a different Actor.
AZ_Assert(false, "AtomActorInstance::SetModelAssetId not supported");
}
Data::AssetId AtomActorInstance::GetModelAssetId() const
@@ -234,8 +241,11 @@ namespace AZ
void AtomActorInstance::SetModelAssetPath([[maybe_unused]] const AZStd::string& modelAssetPath)
{
// Atom Actor Instance is not based on an actual Model Asset yet,
// it's created at runtime from an Actor Asset.
// Changing model asset is not supported by Atom Actor Instance.
// The model asset is obtained from the Actor inside the ActorAsset,
// which is passed to the constructor. To set a different model asset
// this instance should use a different Actor.
AZ_Assert(false, "AtomActorInstance::SetModelAssetPath not supported");
}
AZStd::string AtomActorInstance::GetModelAssetPath() const
@@ -278,28 +288,6 @@ namespace AZ
return IsVisible();
}
void AtomActorInstance::SetMeshAsset(const AZ::Data::AssetId& id)
{
AZ::Data::Asset<EMotionFX::Integration::ActorAsset> asset =
AZ::Data::AssetManager::Instance().GetAsset<EMotionFX::Integration::ActorAsset>(
id, m_actorAsset.GetAutoLoadBehavior());
if (asset)
{
m_actorAsset = asset;
Create();
}
}
AZ::Data::Asset<AZ::Data::AssetData> AtomActorInstance::GetMeshAsset()
{
return m_actorAsset;
}
bool AtomActorInstance::GetVisibility()
{
return static_cast<const AtomActorInstance&>(*this).GetVisibility();
}
AZ::u32 AtomActorInstance::GetJointCount()
{
return m_actorInstance->GetActor()->GetSkeleton()->GetNumNodes();
@@ -469,7 +457,6 @@ namespace AZ
TransformNotificationBus::Handler::BusConnect(m_entityId);
MaterialComponentNotificationBus::Handler::BusConnect(m_entityId);
MeshComponentRequestBus::Handler::BusConnect(m_entityId);
LmbrCentral::MeshComponentRequestBus::Handler::BusConnect(m_entityId);
const Data::Instance<RPI::Model> model = m_meshFeatureProcessor->GetModel(*m_meshHandle);
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelReady, model->GetModelAsset(), model);
@@ -479,7 +466,6 @@ namespace AZ
{
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelPreDestroy);
LmbrCentral::MeshComponentRequestBus::Handler::BusDisconnect();
MeshComponentRequestBus::Handler::BusDisconnect();
MaterialComponentNotificationBus::Handler::BusDisconnect();
TransformNotificationBus::Handler::BusDisconnect();
@@ -62,7 +62,6 @@ namespace AZ
, public AzFramework::BoundsRequestBus::Handler
, public AZ::Render::MaterialComponentNotificationBus::Handler
, public AZ::Render::MeshComponentRequestBus::Handler
, public LmbrCentral::MeshComponentRequestBus::Handler
, private AZ::Render::SkinnedMeshFeatureProcessorNotificationBus::Handler
, private AZ::Render::SkinnedMeshOutputStreamNotificationBus::Handler
, private LmbrCentral::SkeletalHierarchyRequestBus::Handler
@@ -143,14 +142,6 @@ namespace AZ
bool GetVisibility() const override;
// GetWorldBounds/GetLocalBounds already overridden by BoundsRequestBus::Handler
//////////////////////////////////////////////////////////////////////////
// LmbrCentral::MeshComponentRequestBus::Handler
void SetMeshAsset(const AZ::Data::AssetId& id) override;
AZ::Data::Asset<AZ::Data::AssetData> GetMeshAsset() override;
bool GetVisibility() override;
// SetVisibility already overridden by MeshComponentRequestBus::Handler
// GetWorldBounds/GetLocalBounds already overridden by BoundsRequestBus::Handler
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SkeletalHierarchyRequestBus::Handler overrides...
AZ::u32 GetJointCount() override;
@@ -448,9 +448,18 @@ namespace NvCloth
const auto& renderTangents = renderData.m_tangents;
const auto& renderBitangents = renderData.m_bitangents;
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset;
AZ::Render::MeshComponentRequestBus::EventResult(
modelAsset, m_entityId, &AZ::Render::MeshComponentRequestBus::Events::GetModelAsset);
// Since Atom has a 1:1 relation with between ModelAsset buffers and Model buffers,
// internally it created a new asset for the model instance. So it's important to
// get the asset from the model when we want to write to them, instead of getting the
// ModelAsset directly from the bus (which returns the original asset shared by all entities).
AZ::Data::Instance<AZ::RPI::Model> model;
AZ::Render::MeshComponentRequestBus::EventResult(model, m_entityId, &AZ::Render::MeshComponentRequestBus::Events::GetModel);
if (!model)
{
return;
}
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = model->GetModelAsset();
if (!modelAsset.IsReady())
{
return;
+3 -23
View File
@@ -13,11 +13,7 @@
#include <Utils/AssetHelper.h>
#include <Utils/MeshAssetHelper.h>
#include <Utils/ActorAssetHelper.h>
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
#include <Integration/ActorComponentBus.h>
namespace NvCloth
{
@@ -30,25 +26,9 @@ namespace NvCloth
AZStd::unique_ptr<AssetHelper> AssetHelper::CreateAssetHelper(AZ::EntityId entityId)
{
// Does the entity have an Actor Asset?
EMotionFX::ActorInstance* actorInstance = nullptr;
EMotionFX::Integration::ActorComponentRequestBus::EventResult(
actorInstance, entityId, &EMotionFX::Integration::ActorComponentRequestBus::Events::GetActorInstance);
if (actorInstance)
{
return AZStd::make_unique<ActorAssetHelper>(entityId);
}
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset;
AZ::Render::MeshComponentRequestBus::EventResult(
modelAsset, entityId, &AZ::Render::MeshComponentRequestBus::Events::GetModelAsset);
if (modelAsset.GetId().IsValid())
{
return AZStd::make_unique<MeshAssetHelper>(entityId);
}
AZ_Warning("AssetHelper", false, "Unexpected asset type");
return nullptr;
return entityId.IsValid()
? AZStd::make_unique<MeshAssetHelper>(entityId)
: nullptr;
}
float AssetHelper::ConvertBackstopOffset(float backstopOffset)
@@ -14,11 +14,17 @@
#include <Utils/MeshAssetHelper.h>
#include <Integration/ActorComponentBus.h>
namespace NvCloth
{
MeshAssetHelper::MeshAssetHelper(AZ::EntityId entityId)
: AssetHelper(entityId)
{
EMotionFX::ActorInstance* actorInstance = nullptr;
EMotionFX::Integration::ActorComponentRequestBus::EventResult(
actorInstance, entityId, &EMotionFX::Integration::ActorComponentRequestBus::Events::GetActorInstance);
m_supportSkinnedAnimation = actorInstance != nullptr;
}
void MeshAssetHelper::GatherClothMeshNodes(MeshNodeList& meshNodes)
@@ -35,12 +35,14 @@ namespace NvCloth
MeshClothInfo& meshClothInfo) override;
bool DoesSupportSkinnedAnimation() const override
{
return false;
return m_supportSkinnedAnimation;
}
private:
bool CopyDataFromMeshes(
const AZStd::vector<const AZ::RPI::ModelLodAsset::Mesh*>& meshes,
MeshClothInfo& meshClothInfo);
bool m_supportSkinnedAnimation = false;
};
} // namespace NvCloth