Chaos Field Meta Data Filter not working

I’ve encountered some problems with using MetaDataFilters in Chaos Fields.
This happens on the UE5.1 release build from the launcher.

What I’m trying to do: applying a field only on certain Types.
I’ve read this thread Field System not working for Chaos destruction and downloaded the sample project files.

The meta data filtering works as expected for the Sleeping/Disable/Kill field:

However, When I try to implement the same logic to apply external strain, applying a MetaDataFilter (even with State Type and Object Type set to All) results in nothing happening.

Setup: A GeometryCollectionActor with a simple Box Geometry collection:

This Geometry actor is placed above ground.

Then, I created a Blueprint inheriting from FieldSystemActor. Event graph tick function looks like this: A simple box falloff applying external strain.

In the map, I place this field overlapping with the GeomActor:
image

Now two scenario’s:

  • With Meta Data Filter: box does not break
  • With Meta Data Filter node disconnected: box does break.

I took a look at the code to see what’s happening differently.
The filter gets checked in FieldSystemProxyHelper.h:

//if (LocalProxy && ( (PrevResolutionType != ResolutionType) || (PrevFilterType != FilterType) || (PrevObjectType != ObjectType) || (PrevPositionType != PositionType) || FilteredHandles.Num() == 0))
{
	if (FilterType != EFieldFilterType::Field_Filter_Max)
	{
		LocalProxy->GetFilteredParticleHandles(FilteredHandles, RigidSolver, FilterType, ObjectType);
	}
	else
	{
		LocalProxy->GetRelevantParticleHandles(FilteredHandles, RigidSolver, ResolutionType);
	}
...

Depending on the presence of the MetaDataFilter, one of the two paths gets executed.
These two functions reside in PerSolverFieldSystem.cpp.

The big difference between the two I observed when debugging, is that when no filter is applied (and thus GetRelevantParticleHandles is called), there is an additional lookup of clusters within each Handle:

for (Chaos::TParticleIterator<Chaos::FGeometryParticles> It = ParticleView.Begin(), ItEnd = ParticleView.End();
			It != ItEnd; ++It)
{
	const Chaos::TTransientGeometryParticleHandle<Chaos::FReal,3>* Handle = &(*It);
			Handles.Add(GetHandleHelper(const_cast<Chaos::TTransientGeometryParticleHandle<Chaos::FReal,3>*>(Handle)));	

	const auto* Clustered = Handle->CastToClustered();
	if (Clustered && Clustered->ClusterIds().NumChildren)
	{
		Chaos::TPBDRigidClusteredParticleHandle<Chaos::FReal, 3>* ClusterHandle = (*It).Handle()->CastToClustered();
		if (ClusterMap.Contains(ClusterHandle))
		{
			for (Chaos::TPBDRigidParticleHandle<Chaos::FReal, 3> * Child : ClusterMap[ClusterHandle])
			{
				Handles.Add(Child);
			}
		}
	}
}

(This only happens when the Resolution Type is set to EFieldResolutionType::Field_Resolution_Minimal. (Which is the default value, afaik.)

In the other function (GetFilteredParticleHandles), only handles within the view get added, and not their possible cluster children:

else if (FilterType == EFieldFilterType::Field_Filter_All)
{
	const Chaos::TParticleView<Chaos::FGeometryParticles>& ParticleView =
		SolverParticles.GetNonDisabledView();
	Handles.Reserve(ParticleView.Num());

	for (Chaos::TParticleIterator<Chaos::FGeometryParticles> It = ParticleView.Begin(), ItEnd = ParticleView.End();
			It != ItEnd; ++It)
	{
		if (ValidateParticle(ObjectType, It))
		{
			const Chaos::TTransientGeometryParticleHandle<Chaos::FReal, 3>* Handle = &(*It);
				Handles.Add(GetHandleHelper(const_cast<Chaos::TTransientGeometryParticleHandle<Chaos::FReal, 3>*>(Handle)));
		}
	}
}

Any help much appreciated.

1 Like

I am also experiencing strangeness with the Meta Data property - in my case, I can’t actually apply any filtering to the sleep/disable/kill field, which apparently is working in your case. In mine, applying any object type or state filter does not change its behaviour, e.g. a chaos geo collection entering the sleep field will still sleep even if the object type filter is set to ‘cloth’.