Fix cloth receiving weird impulses when actors are spawned

This commit is contained in:
Aaron Ruiz Mora
2021-05-17 12:28:08 +01:00
committed by GitHub
parent 1d87e25c29
commit 4798c1cadd
2 changed files with 14 additions and 12 deletions
@@ -36,6 +36,9 @@ namespace NvCloth
AZ_CVAR(float, cloth_DistanceToTeleport, 0.5f, nullptr, AZ::ConsoleFunctorFlags::Null,
"The amount of meters the entity has to move in a frame to consider it a teleport for cloth.");
AZ_CVAR(float, cloth_SecondsToDelaySimulationOnActorSpawned, 0.25f, nullptr, AZ::ConsoleFunctorFlags::Null,
"The amount of time in seconds the cloth simulation will be delayed to avoid sudden impulses when actors are spawned.");
// Helper class to map an RPI buffer from a buffer asset view.
template<typename T>
class MappedBuffer
@@ -190,7 +193,7 @@ namespace NvCloth
m_meshClothInfo.m_particles,
m_cloth->GetParticles().size(),
m_meshRemappedVertices);
m_numberOfClothSkinningUpdates = 0;
m_timeClothSkinningUpdates = 0.0f;
m_clothConstraints = ClothConstraints::Create(
m_meshClothInfo.m_motionConstraints,
@@ -248,7 +251,7 @@ namespace NvCloth
void ClothComponentMesh::OnPreSimulation(
[[maybe_unused]] ClothId clothId,
[[maybe_unused]] float deltaTime)
float deltaTime)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Cloth);
@@ -256,7 +259,7 @@ namespace NvCloth
if (m_actorClothSkinning)
{
UpdateSimulationSkinning();
UpdateSimulationSkinning(deltaTime);
UpdateSimulationConstraints();
}
@@ -338,7 +341,7 @@ namespace NvCloth
}
}
void ClothComponentMesh::UpdateSimulationSkinning()
void ClothComponentMesh::UpdateSimulationSkinning(float deltaTime)
{
if (m_actorClothSkinning)
{
@@ -349,22 +352,21 @@ namespace NvCloth
// Since component activation order is not trivial, the actor's pose might not be updated
// immediately. Because of this cloth will receive a sudden impulse when changing from
// T pose to animated pose. To avoid this undesired effect we will override cloth simulation during
// a short amount of frames.
const AZ::u32 numberOfTicksToDoFullSkinning = 10;
m_numberOfClothSkinningUpdates++;
// a short amount of time.
m_timeClothSkinningUpdates += deltaTime;
// While the actor is not visible the skinned joints are not updated. Then when
// it becomes visible the jump to the new skinned positions causes a sudden
// impulse to cloth simulation. To avoid this undesired effect we will override cloth simulation during
// a short amount of frames.
// a short amount of time.
m_actorClothSkinning->UpdateActorVisibility();
if (!m_actorClothSkinning->WasActorVisible() &&
m_actorClothSkinning->IsActorVisible())
{
m_numberOfClothSkinningUpdates = 0;
m_timeClothSkinningUpdates = 0.0f;
}
if (m_numberOfClothSkinningUpdates <= numberOfTicksToDoFullSkinning)
if (m_timeClothSkinningUpdates <= cloth_SecondsToDelaySimulationOnActorSpawned)
{
// Update skinning for all particles and apply it to cloth
AZStd::vector<SimParticleFormat> particles = m_cloth->GetParticles();
@@ -85,7 +85,7 @@ namespace NvCloth
private:
void UpdateSimulationCollisions();
void UpdateSimulationSkinning();
void UpdateSimulationSkinning(float deltaTime);
void UpdateSimulationConstraints();
void UpdateRenderData(const AZStd::vector<SimParticleFormat>& particles);
@@ -133,7 +133,7 @@ namespace NvCloth
// Cloth Skinning from the character
AZStd::unique_ptr<ActorClothSkinning> m_actorClothSkinning;
AZ::u32 m_numberOfClothSkinningUpdates = 0;
float m_timeClothSkinningUpdates = 0.0f;
// Cloth Constraints
AZStd::unique_ptr<ClothConstraints> m_clothConstraints;