Add debug sanity checks to cloth to solve issues
This commit is contained in:
@@ -133,7 +133,7 @@ Array<Float3> Cloth::GetParticles() const
|
|||||||
void Cloth::SetParticles(Span<const Float3> value)
|
void Cloth::SetParticles(Span<const Float3> value)
|
||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
#if !BUILD_RELEASE
|
#if USE_CLOTH_SANITY_CHECKS
|
||||||
{
|
{
|
||||||
// Sanity check
|
// Sanity check
|
||||||
const Float3* src = value.Get();
|
const Float3* src = value.Get();
|
||||||
@@ -162,6 +162,16 @@ Span<float> Cloth::GetPaint() const
|
|||||||
void Cloth::SetPaint(Span<const float> value)
|
void Cloth::SetPaint(Span<const float> value)
|
||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
|
#if USE_CLOTH_SANITY_CHECKS
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
const float* src = value.Get();
|
||||||
|
bool allValid = true;
|
||||||
|
for (int32 i = 0; i < value.Length(); i++)
|
||||||
|
allValid &= !isnan(src[i]) && !isinf(src[i]);
|
||||||
|
ASSERT(allValid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (value.IsInvalid())
|
if (value.IsInvalid())
|
||||||
{
|
{
|
||||||
// Remove paint when set to empty
|
// Remove paint when set to empty
|
||||||
@@ -174,16 +184,6 @@ void Cloth::SetPaint(Span<const float> value)
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if !BUILD_RELEASE
|
|
||||||
{
|
|
||||||
// Sanity check
|
|
||||||
const float* src = value.Get();
|
|
||||||
bool allValid = true;
|
|
||||||
for (int32 i = 0; i < value.Length(); i++)
|
|
||||||
allValid &= !isnan(src[i]) && !isinf(src[i]);
|
|
||||||
ASSERT(allValid);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_paint.Set(value.Get(), value.Length());
|
_paint.Set(value.Get(), value.Length());
|
||||||
#if WITH_CLOTH
|
#if WITH_CLOTH
|
||||||
if (_cloth)
|
if (_cloth)
|
||||||
@@ -295,6 +295,17 @@ void Cloth::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
|||||||
DESERIALIZE_MEMBER(Fabric, _fabricSettings);
|
DESERIALIZE_MEMBER(Fabric, _fabricSettings);
|
||||||
DESERIALIZE_MEMBER(Paint, _paint);
|
DESERIALIZE_MEMBER(Paint, _paint);
|
||||||
|
|
||||||
|
#if USE_CLOTH_SANITY_CHECKS
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
const float* data = _paint.Get();
|
||||||
|
bool allValid = true;
|
||||||
|
for (int32 i = 0; i < _paint.Count(); i++)
|
||||||
|
allValid &= !isnan(data[i]) && !isinf(data[i]);
|
||||||
|
ASSERT(allValid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Refresh cloth when settings were changed
|
// Refresh cloth when settings were changed
|
||||||
if (IsDuringPlay())
|
if (IsDuringPlay())
|
||||||
Rebuild();
|
Rebuild();
|
||||||
@@ -588,6 +599,7 @@ void Cloth::CalculateInvMasses(Array<float>& invMasses)
|
|||||||
|
|
||||||
// Sum triangle area for each influenced particle
|
// Sum triangle area for each influenced particle
|
||||||
invMasses.Resize(verticesCount);
|
invMasses.Resize(verticesCount);
|
||||||
|
invMasses.SetAll(0.0f);
|
||||||
for (int32 triangleIndex = 0; triangleIndex < trianglesCount; triangleIndex++)
|
for (int32 triangleIndex = 0; triangleIndex < trianglesCount; triangleIndex++)
|
||||||
{
|
{
|
||||||
const int32 index = triangleIndex * 3;
|
const int32 index = triangleIndex * 3;
|
||||||
@@ -621,6 +633,10 @@ void Cloth::CalculateInvMasses(Array<float>& invMasses)
|
|||||||
for (int32 i = 0; i < verticesCount; i++)
|
for (int32 i = 0; i < verticesCount; i++)
|
||||||
{
|
{
|
||||||
float& mass = invMasses[i];
|
float& mass = invMasses[i];
|
||||||
|
#if USE_CLOTH_SANITY_CHECKS
|
||||||
|
// Sanity check
|
||||||
|
ASSERT(!isnan(mass) && !isinf(mass) && mass >= 0.0f);
|
||||||
|
#endif
|
||||||
const float maxDistance = _paint[i];
|
const float maxDistance = _paint[i];
|
||||||
if (maxDistance < 0.01f)
|
if (maxDistance < 0.01f)
|
||||||
{
|
{
|
||||||
@@ -649,6 +665,17 @@ void Cloth::CalculateInvMasses(Array<float>& invMasses)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_CLOTH_SANITY_CHECKS
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
const float* data = invMasses.Get();
|
||||||
|
bool allValid = true;
|
||||||
|
for (int32 i = 0; i < invMasses.Count(); i++)
|
||||||
|
allValid &= !isnan(data[i]) && !isinf(data[i]);
|
||||||
|
ASSERT(allValid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
#include "Engine/Level/Actor.h"
|
#include "Engine/Level/Actor.h"
|
||||||
#include "Engine/Level/Actors/ModelInstanceActor.h"
|
#include "Engine/Level/Actors/ModelInstanceActor.h"
|
||||||
|
|
||||||
|
// Used internally to validate cloth data against invalid nan/inf values
|
||||||
|
#define USE_CLOTH_SANITY_CHECKS (BUILD_DEBUG)
|
||||||
|
|
||||||
/// <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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -3328,6 +3328,32 @@ void PhysicsBackend::RemoveVehicle(void* scene, WheeledVehicle* actor)
|
|||||||
|
|
||||||
void* PhysicsBackend::CreateCloth(const PhysicsClothDesc& desc)
|
void* PhysicsBackend::CreateCloth(const PhysicsClothDesc& desc)
|
||||||
{
|
{
|
||||||
|
#if USE_CLOTH_SANITY_CHECKS
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
bool allValid = true;
|
||||||
|
for (int32 i = 0; i < desc.VerticesCount; i++)
|
||||||
|
allValid &= !(*(Float3*)((byte*)desc.VerticesData + i * desc.VerticesStride)).IsNanOrInfinity();
|
||||||
|
if (desc.InvMassesData)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < desc.VerticesCount; i++)
|
||||||
|
{
|
||||||
|
float v = *(float*)((byte*)desc.InvMassesData + i * desc.InvMassesStride);
|
||||||
|
allValid &= !isnan(v) && !isinf(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (desc.MaxDistancesData)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < desc.VerticesCount; i++)
|
||||||
|
{
|
||||||
|
float v = *(float*)((byte*)desc.MaxDistancesData + i * desc.MaxDistancesStride);
|
||||||
|
allValid &= !isnan(v) && !isinf(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT(allValid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Lazy-init NvCloth
|
// Lazy-init NvCloth
|
||||||
if (ClothFactory == nullptr)
|
if (ClothFactory == nullptr)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user