Request: Add an option to restrict physics volumes to only affect a subset of navmeshes.

Good afternoon,

We would like to request the ability to have some physics objects only affect a subset of our recast navmeshes, ideally without requiring intrusive engine edits. Nav modifier volumes are inadequate for this in an open world game, this would add tens of thousands of extra actors and components to the world, and the resulting nav areas would negatively affect the fidelity of pathfinding.

Cheers,

-Ian Stitzlein

[Attachment Removed]

It looks like that may be an issue from how we expand dynamic obstacles rather than erode walkable areas with voxels. I’m trying in a local project with some default assets, but I’m not seeing the corner being cut. I have found some code that could possibly be the culprit, but want to make sure I am following the correct line of though on it. I think a point may be getting removed in a deduplication check that the point is a minimum distance away. Can you add a log or watch for ConvexData.Points.Num() just before line 5547 in FRecastTileGenerator::MarkDynamicArea?

And as a sanity check, are you on 5.7 for your current testing?

-James

[Attachment Removed]

I am on 5.7. I’ll try and add a breakpoint there, but here are our settings for this navmesh/agent. [Image Removed]

[Image Removed]

[Attachment Removed]

FYI, not seeing that line of code in this version.

[Image Removed]

[Attachment Removed]

I am working out of our main branch which apparently has lots of code added. In 5.7, it should be about line 4903 where there should be

else
{
	Modifier.GetConvex(ConvexData);
}

I am interested in what is sent with the convex data. I have been looking through our JIRA to see if we possibly made a change to this, but I don’t see anything on the navigation front. It is possible another team bumped into it and fixed it between versions. It would certainly be grand to have a CL to share that fixes this, but I believe it might be lurking there but need some other circumstance to cause that my simple test level does not have.

-James

[Attachment Removed]

Reproed this in an empty level, with our settings. Here is the convex data that came back, and the resulting navmesh. It doesnt do it everywhere, I had to drag the box around a bit to repro this.

[Image Removed]

[Attachment Removed]

Thank you so much! I absolutely love when users share back so much info to help us find all of this!

I think I may have a fix for this particular problem. I would be very grateful if you could test it out since you have a repro to ensure it really does fix the issue. In FRecastTileGenerator::MarkDynamicArea at the very beginning of the method on line 4814 change the expansion used to be more like what is done when eroding the area. The change would be this:

// OLD:                                                                                                                                                                                                                                                                            
// const float ExpandBy = TileConfig.AgentRadius;                                                                                                                                                                                                                                  
const float ExpandBy = FMath::CeilToFloat(TileConfig.AgentRadius / TileConfig.cs) * TileConfig.cs;

Would you be able to test this out for me? If it works, I will get things pushed into the main branch and see about getting this included into a 5.8 hotfix.

-James

[Attachment Removed]

Did not seem to fix it. Does this use a completely different recast code path? It looks like there is more going on here than just the object padding being different.

[Image Removed]

[Attachment Removed]

There are two separate paths for static mesh and obstacles. Obstacles skip over one of the triangles being voxelized into the heightfield. The change should fix some issues. I have been setting up a test of my own, and I am unable to get exact matchups of shapes due to this change. The obstacle should produce better footprints for meshes, but there could be issues with concave geometry. There may be a way to address that, but it would be outside the hotfix rules. I would also need to test it much deeper for perf to rasterize the triangles as one of the benefits of obstacles is that they are much faster to build for dynamic navmesh because it skips some of the rasterization steps.

The image of the obstacle looks closer to what I would expect. If you use the Top orthographic view for the level, can you measure the distance from the edge of the mesh to the navmesh edge? You can do this very quickly by click dragging middle mouse button. You will want to turn off grid snapping though to get accurate results. The corners will be larger by how the expansion works, but the sides should be roughly your agent radius.

-James

[Attachment Removed]

Looks shy by about 12cm.

[Image Removed]

[Attachment Removed]

Hmm… I had a similar setup in the test project I was using, but changing the offset changed things after building the navmesh. It is something I will dive back into to see what I can find for this. It certainly is part of the perf tradeoff we made for dynamic obstacles in the engine. You could remove the optimization when triangles are being voxelized that checks for an object, but that would incur more generation cost for the navmesh. I think that would make Dynamic Modifiers Only no longer work properly, but that might not be an issue in a fully static or dynamic navmesh.

-James

[Attachment Removed]

I would not expect that tight of a cut. Can you add a log in MarkDynamicArea to print out the TileConfig.AgentRadius, TileConfig.cs, and the value of ExpandBy the expansion? At your config (34/19) the formula should compute ExpandBy = 38. If it shows 34, the code change isn’t actually taking effect (Live Coding vs full rebuild, wrong module, etc.) and the 22-uu clearance you’re seeing is the original code path. I believe the worst case scenario from the original code would be a 24.5uu perpendicular from the side, and I want to make sure the math is matching.

Unfortunately, there is not a good way to fully reproduce the geometry of a mesh with the dynamic obstacle since it skips rasterization.

-James

[Attachment Removed]

Its trying to do the right thing sometimes, but it definitely shows some weirdness as I drag it around.

[Attachment Removed]

Interestingly, it doesnt look like the ExpandBy is actually doing anything in GrowConvexHull().

LogNavigation: Warning: FRecastTileGenerator::MarkDynamicArea ConvexData.Points: 
  X=156.971 Y=-600.422 Z=0.000
  X=156.971 Y=-800.422 Z=0.000
  X=456.971 Y=-800.422 Z=0.000
  X=456.971 Y=-600.422 Z=0.000
LogNavigation: Warning: FRecastTileGenerator::MarkDynamicArea ConvexVerts: 
  X=156.971 Y=-600.422 Z=0.000
  X=156.971 Y=-800.422 Z=0.000
  X=456.971 Y=-800.422 Z=0.000
  X=456.971 Y=-600.422 Z=0.000
UE_LOG(LogNavigation, Warning, TEXT("FRecastTileGenerator::MarkDynamicArea ConvexData.Points: \n  %s\n  %s\n  %s\n  %s"), *ConvexData.Points[0].ToString(), *ConvexData.Points[1].ToString(), *ConvexData.Points[2].ToString(), *ConvexData.Points[3].ToString());
 
const TArray<FVector> Points = UE::LWC::ConvertArrayType<FVector>(ConvexData.Points);
GrowConvexHull(ExpandBy, Points, ConvexVerts);
ConvexData.MinZ -= OffsetZMin;
ConvexData.MaxZ += OffsetZMax;
 
UE_LOG(LogNavigation, Warning, TEXT("FRecastTileGenerator::MarkDynamicArea ConvexVerts: \n  %s\n  %s\n  %s\n  %s"), *ConvexVerts[0].ToString(), *ConvexVerts[1].ToString(), *ConvexVerts[2].ToString(), *ConvexVerts[3].ToString());

[Attachment Removed]

Hi Ian,

I’ve been trying different methods to fix this after I got a repro with the changes I had sent you locally. So far, I have only found that increasing the bounds to really ensure this does not happen. That covers the worst-case scenario of modifiers, but it means the average case cuts out more space than it really needs which could cause issues in tight spaces.

I am trying to get in touch with some of our folks working on Fortnite who have done some work previously to support large agents in BR. I have not heard back from them yet, but will update you with anything I find that could be helpful.

-James

[Attachment Removed]

On it.

[Attachment Removed]

Any follow-up you need from my end?

[Attachment Removed]

Looks like the ExpandBy looks correct.

[Image Removed]

[Attachment Removed]