Don't update cloth colliders every frame

This commit is contained in:
Wojtek Figat
2023-07-16 12:53:59 +02:00
parent 9179586f14
commit adfaf8c961
3 changed files with 20 additions and 4 deletions

View File

@@ -723,6 +723,7 @@ void Cloth::OnPreUpdate()
int32 verticesCount; int32 verticesCount;
if (mesh.Actor->GetMeshData(mesh, MeshBufferType::Vertex0, verticesData, verticesCount)) if (mesh.Actor->GetMeshData(mesh, MeshBufferType::Vertex0, verticesData, verticesCount))
return; return;
PROFILE_CPU_NAMED("Skinned Pose");
auto vbStride = (uint32)verticesData.Length() / verticesCount; auto vbStride = (uint32)verticesData.Length() / verticesCount;
ASSERT(vbStride == sizeof(VB0SkinnedElementType)); ASSERT(vbStride == sizeof(VB0SkinnedElementType));
PhysicsBackend::LockClothParticles(_cloth); PhysicsBackend::LockClothParticles(_cloth);
@@ -835,6 +836,7 @@ void Cloth::RunClothDeformer(const MeshBase* mesh, MeshDeformationData& deformat
if ((_simulationSettings.ComputeNormals || deformation.Type == MeshBufferType::Vertex1) && if ((_simulationSettings.ComputeNormals || deformation.Type == MeshBufferType::Vertex1) &&
meshRef.Actor && !meshRef.Actor->GetMeshData(meshRef, MeshBufferType::Index, indicesData, indicesCount)) meshRef.Actor && !meshRef.Actor->GetMeshData(meshRef, MeshBufferType::Index, indicesData, indicesCount))
{ {
PROFILE_CPU_NAMED("Normals");
// TODO: optimize memory allocs (eg. use shared allocator) // TODO: optimize memory allocs (eg. use shared allocator)
normals.Resize(vbCount); normals.Resize(vbCount);
Platform::MemoryClear(normals.Get(), vbCount * sizeof(Float3)); Platform::MemoryClear(normals.Get(), vbCount * sizeof(Float3));

View File

@@ -6,7 +6,7 @@
#include "Engine/Level/Actors/ModelInstanceActor.h" #include "Engine/Level/Actors/ModelInstanceActor.h"
// Used internally to validate cloth data against invalid nan/inf values // Used internally to validate cloth data against invalid nan/inf values
#define USE_CLOTH_SANITY_CHECKS (BUILD_DEBUG) #define USE_CLOTH_SANITY_CHECKS 0
/// <summary> /// <summary>
/// Physical simulation actor for cloth objects made of vertices that are simulated as cloth particles with physical properties, forces, and constraints to affect cloth behavior. /// Physical simulation actor for cloth objects made of vertices that are simulated as cloth particles with physical properties, forces, and constraints to affect cloth behavior.

View File

@@ -48,6 +48,7 @@
#include <ThirdParty/NvCloth/NvClothExt/ClothFabricCooker.h> #include <ThirdParty/NvCloth/NvClothExt/ClothFabricCooker.h>
#define MAX_CLOTH_SPHERE_COUNT 32 #define MAX_CLOTH_SPHERE_COUNT 32
#define MAX_CLOTH_PLANE_COUNT 32 #define MAX_CLOTH_PLANE_COUNT 32
#define CLOTH_COLLISIONS_UPDATE_RATE 10 // Frames between cloth collisions updates
#endif #endif
#if WITH_PVD #if WITH_PVD
#include <ThirdParty/PhysX/pvd/PxPvd.h> #include <ThirdParty/PhysX/pvd/PxPvd.h>
@@ -151,6 +152,8 @@ struct FabricSettings
struct ClothSettings struct ClothSettings
{ {
bool SceneCollisions = false; bool SceneCollisions = false;
byte CollisionsUpdateFramesLeft = 0;
bool CollisionsUpdateFramesRandomize = true;
float GravityScale = 1.0f; float GravityScale = 1.0f;
float CollisionThickness = 0.0f; float CollisionThickness = 0.0f;
Cloth* Actor; Cloth* Actor;
@@ -1425,7 +1428,7 @@ void PhysicsBackend::EndSimulateScene(void* scene)
// TODO: jobify to run in async (eg. with vehicles update and events setup) // TODO: jobify to run in async (eg. with vehicles update and events setup)
{ {
PROFILE_CPU_NAMED("Collisions"); PROFILE_CPU_NAMED("Pre");
const bool hitTriggers = false; const bool hitTriggers = false;
const bool blockSingle = false; const bool blockSingle = false;
PxQueryFilterData filterData; PxQueryFilterData filterData;
@@ -1435,12 +1438,20 @@ void PhysicsBackend::EndSimulateScene(void* scene)
for (int32 i = 0; i < clothsCount; i++) for (int32 i = 0; i < clothsCount; i++)
{ {
auto clothPhysX = (nv::cloth::Cloth*)cloths[i]; auto clothPhysX = (nv::cloth::Cloth*)cloths[i];
const auto& clothSettings = Cloths[clothPhysX]; auto& clothSettings = Cloths[clothPhysX];
clothSettings.Actor->OnPreUpdate(); clothSettings.Actor->OnPreUpdate();
// Setup automatic scene collisions with colliders around the cloth // Setup automatic scene collisions with colliders around the cloth
if (clothSettings.SceneCollisions) if (clothSettings.SceneCollisions && clothSettings.CollisionsUpdateFramesLeft == 0)
{ {
PROFILE_CPU_NAMED("Collisions");
clothSettings.CollisionsUpdateFramesLeft = CLOTH_COLLISIONS_UPDATE_RATE;
if (clothSettings.CollisionsUpdateFramesRandomize)
{
clothSettings.CollisionsUpdateFramesRandomize = false;
clothSettings.CollisionsUpdateFramesLeft = i % CLOTH_COLLISIONS_UPDATE_RATE;
}
// Reset existing colliders // Reset existing colliders
clothPhysX->setSpheres(nv::cloth::Range<const PxVec4>(), 0, clothPhysX->getNumSpheres()); clothPhysX->setSpheres(nv::cloth::Range<const PxVec4>(), 0, clothPhysX->getNumSpheres());
clothPhysX->setPlanes(nv::cloth::Range<const PxVec4>(), 0, clothPhysX->getNumPlanes()); clothPhysX->setPlanes(nv::cloth::Range<const PxVec4>(), 0, clothPhysX->getNumPlanes());
@@ -1587,6 +1598,7 @@ void PhysicsBackend::EndSimulateScene(void* scene)
} }
} }
} }
clothSettings.CollisionsUpdateFramesLeft--;
} }
} }
@@ -3475,6 +3487,7 @@ void PhysicsBackend::SetClothCollisionSettings(void* cloth, const void* settings
clothPhysX->setPlanes(nv::cloth::Range<const PxVec4>(), 0, clothPhysX->getNumPlanes()); clothPhysX->setPlanes(nv::cloth::Range<const PxVec4>(), 0, clothPhysX->getNumPlanes());
clothPhysX->setTriangles(nv::cloth::Range<const PxVec3>(), 0, clothPhysX->getNumTriangles()); clothPhysX->setTriangles(nv::cloth::Range<const PxVec3>(), 0, clothPhysX->getNumTriangles());
} }
clothSettings.CollisionsUpdateFramesLeft = 0;
clothSettings.SceneCollisions = settings.SceneCollisions; clothSettings.SceneCollisions = settings.SceneCollisions;
clothSettings.CollisionThickness = settings.CollisionThickness; clothSettings.CollisionThickness = settings.CollisionThickness;
} }
@@ -3536,6 +3549,7 @@ void PhysicsBackend::SetClothTransform(void* cloth, const Transform& transform,
clothPhysX->setRotation(C2P(transform.Orientation)); clothPhysX->setRotation(C2P(transform.Orientation));
} }
const auto& clothSettings = Cloths[clothPhysX]; const auto& clothSettings = Cloths[clothPhysX];
clothSettings.CollisionsUpdateFramesLeft = 0;
clothSettings.UpdateBounds(clothPhysX); clothSettings.UpdateBounds(clothPhysX);
} }