How to read collision mesh data and primitives from a StaticMeshComponent in C++

I would like to convert the collision data embedded into a static mesh into a format of our own.

However I have yet to understand how the collision data (primitives such as boxes, spheres etc and the triangular mesh if any) can be read out of a static mesh.

Unreal documentation is very limited when it comes to C++.

Can any experienced unreal programmer or the staff can give a few hints about how this can be done.

Thanks in advance.

1 Like

I found a way to do it.

The collision data is kept within the UBodySetup inside UStaticMesh, which you can get from a StaticMeshComponent via GetStaticMesh method.

Within the UBodySetup there is the data structure AggGeom of type FKAggregateGeom. This appears protected in code. However it is somehow exposed to the external C++ classes.

There are 4 arrays inside this class (BoxElems, SphereElems, SphylElems, ConvexElems) that correspond to each of the four collision body types added to the StaticMesh for collision detection.

Reading the first three (primitive colliders) is trivial. You just need to iterate through the arrays and read parameters (center, radius, orientation, etc) of the primitive colliders.

Reading ConvexElems is a little more complicated. The data for each convex element is kept within the data structures provided by the PhysX API. Namely the PxConvexMesh class.

Accessing the methods of PxConvexMesh class requires addition of the “PhysX” module as a public dependency in the *Build.cs file to the project. And then one should include the “PhysXPublic.h” header file within the cpp file you want to read the mesh data.

This will give you access to the internal index and vertex arrays as well as the faces (polygons) of the convex mesh data (stored within PxConvexMesh).

I guess this answers my own question.

4 Likes

Using 4.20 it seems that it requires the “Apex” module as well.

Hello, thank you for sharing this information, I have a question though ,
When I’m uploading the collision directly from the 3d modeling package by UCX prefix your approach works fine, but when I select “Use Collision as simple” for the collision complexity I can’t get the collision data. I tried to dig in the API but no clues as I’m new to unreal, any hints or links would be appreciated.

I’m wondering if there is a way to get that simple collision AggGeom in blueprint. The sweep result returns the body index, but I’m not finding the rest of the information though. I want it at runtime too.

The reason being that you can name your collision prims. So on sweep I can switch on name based on the bone names. The bone name returns the primitive name too. I wanted to get the shapes so I could do a dot product of info from that shape with another shape to see if they are aligned.

The hulls don’t really have names after import.

If you really want to do this / somethign similar anyway, all you have to do is create a c++ function that outputs the data to blueprint for you.
Since c++ has it accessible, flipping the data around to expose it to BP is rather trivial.

In the interest of actually doing it thoug, I’d go with the dot product from c++ and return a boolean of IF they are aligned to BP.
C++ processes things faster, so sending back only a true or false would probably be faster overall than taking the info to BP, running the cross/dot whatever, and figuring things out.

you can manually name your hulls in the collision primitives panel in your static mesh. Your physics asset for skeletal mesh is treated the same as well.

I mean, if you want to go through each asset to do the naming knowing its likely wasted time you’d be better off putting in a sytem that actually works differently by concept… sure. Why not?

Phat assets are a different story either way, And hit results can directly return the name of the bone they hit.
Since there is also a limit around 16 hulls on a phat asset (for phisx cloth reaction at least) - adding multiple hulls to the same bone is normally a bad idea (while it could sometimes be required).
For this too, I’d go some other way about determining impact over primitive name and math…

I just tested my friend’s that has 25+ and it works fine. Doesn’t return hull name though, which it’s supposed to.

(post deleted by author)