Physics.BakeMesh question

In Unity 2019.3, there is the new Physics.BakeMesh API:
https://docs.unity3d.com/2019.3/Documentation/ScriptReference/Physics.BakeMesh.html

If I bake a mesh at runtime and assign it to a MeshCollider, do the cookingOptions in the MeshCollider have any affect? Do I need to set the MeshCollider.cookingOptions to None if I assign a baked mesh?

There seem to be no cookingOptions for Physics.BakeMesh?

The documentation reads:
[quote]
When a MeshCollider referencing this Mesh is instantiated
[/quote]
I don't understand this. When I assign a physics-baked mesh to a MeshCollider, what is being instantiated? I'm dynamically switching MeshCollider meshes at runtime, like through a flipbook. Would this cause any issues?

2 Likes

Thanks for the great in-depth questions.

Let me go through some of the aspects of interaction with MeshCollider.

In practical terms, the most expensive function of MeshCollider is its sharedMesh property (MeshCollider::SetSharedMesh in the native lands if you examined the callstacks).

Changing sharedMesh might cause an expensive cooking/baking run. Whenever the sharedMesh property is changed, we will only reuse the PhysX mesh pointer stored in the Mesh instance if:
- this MeshCollider's cookingOptions are exactly the default ones, AND
- the MeshCollider's transform is good (*), AND
- the Mesh instance hasn't been changed since the last time cooking was ran.

(*) Here, MeshCollider's transform is good when
- it's scaling is not negative and not skewed, OR
- it's scaling can be negative but only when MeshCollider is not convex

(Keep in mind that cooking requires the readable property of the Mesh set)

The cookingOptions are not stored in the Mesh instance, they belong to the MeshCollider instance currently. For that reason we will only write the PhysX mesh pointer back to Mesh if the cookingOptions are default.

Getting back to Physics.BakeMesh - it's supposed to be used in conjunction with MeshColliders that have the default cooking options, as otherwise the PhysX mesh pointer won't be shared.

Does this help?

2 Likes


I think there may actually be a bug in the code that performs the check related to this:
- the Mesh instance hasn't been changed since the last time cooking was ran.

From my experience, the actual behaviour is that the cooking/baking will be performed if the mesh was ever changed after it's initial baking pass, regardless of whether it has changed since the last good bake.

For example:

Modify Mesh
Modify Mesh
Assign sharedmesh
Move collider (bake)
Move collider (no bake)
Move collider (no bake)
Modify Mesh
Move collider (bake) - expected
Move collider (bake) - unexpected

Interesting. Could you file a bug report for easier tracking?

Having a similar issue on some procedural meshes..

I'm doing..

// creating or refreshing mesh verts in job system
gameObject.SetActive(false);
collider.sharedMesh = null;
// creating or rebuilding mesh with new data
// setting mesh filter's sharedmesh
gameObject.SetActive(true);
// Physics.BakeMesh( meshID ); in job system
collider.sharedMesh = mesh;

This seems to result in the following errors:

[Physics.PhysX] Foundation: Invalid deregistration detected. // on the null set
[Physics.PhysX] Foundation: Invalid registration detected. // on the refreshed mesh set

And to top it off, it seems to be rebaking the mesh anyways when setting the sharedMesh ;_;

May I kindly ask you to file a bug using Unity's Bugreporter? You'd get a tracking link for this issue, and everyone will be able to track progress on it. Thanks!


Unfortunately, after restarting Unity this problem seems to have vanished, so now I cannot duplicate it to file a bug report..

@yant However, the double bake does still happen for me. I made a repro, here's the case: #1197040

1 Like


Super cool, I'll take a look. Thanks.


Ever get a chance to look at this? I just updated to 2019.3.0f3 hoping it would be fixed, but I'm still seeing the bake show up in both the job system and the main thread.. (schedules a job to bake a bunch of meshes, then next frame completes the job and sets the meshes to the sharedMesh parameter of their mesh colliders)

5273910--528240--upload_2019-12-11_21-41-58.png

5273910--528243--upload_2019-12-11_21-42-37.png

Yes, I took a look. I think to make the current code work well, it is required:
- Use a new Mesh every time you modify it
- Make sure you actually set the baked mesh to some mesh collider (otherwise it may leak)

^ those issues are getting addressed as we speak, but I have no dates share unfortunately.


Oh, is the issue that a single mesh class instance being rebaked multiple times is not yet supported? I suppose I can work around this, although it does seem like a waste of heap space, in my case it may be acceptable as a workaround. I'll try it, thanks!

It's not exactly like it's not supported, just that a bug makes it broken. Debugging it I find this may be a viable workaround in the meantime.

I can confirm that currently it only seems to bake on fresh meshes. Can't await the fix, i run a procedural Terrain-Generator on mobile:

I use custom meshes paired with Terrains that are only used for their TerrainColliders. Terrain Colliders can be updated about 10 times quicker than an equivalent CookingOption.None-meshcollider
(~1ms vs 10ms, cant be threaded -> lags).

I already do threading on everything else, so finally having the option to thread mesh-collider generation is the best news ever! If this is fixed i can consider any mesh for my terrain, not just heightmapped terrains.

Question: are there any plans to expose the collider-data for a more direct tinkering? E.g. i could use the Terrain-Collider generation speed but with some flipped quads (for polystyle)

My game is all procedural, so i am really interested in this.
Can you please give a link to the issue tracker page, so i can vote on this?


Is there any indication in the profiler if the mesh pointer can't be shared with PhysX? I'm currently writing an import pipeline to create "physics meshes", which are regular meshes ran through Physics.BakeMesh and saved as asset. I then assign these physics meshes to a MeshCollider at runtime and would like to know whether this works without overhead.


When you do get a chance to look deeper at this and work on fixing it, can you ensure that the previously baked collision mesh is still somehow valid until we swap to the new one? Or is it writing to the same buffer, so this is not possible? I may need to make a new mesh anyways (or I suppose, in the future just keep two and swap between them on update) to ensure collision is still valid while the new one is being baked..

I use transformations (including non-uniform scales) of a set of primitive MeshCollider objects to construct collision shape. I get colliders from pools). Needless to say, i'm getting a lot of Physics.Bake now left and right. It would be nice, if we could Physics.Bake(meshID, convex, transform) or Physics.Bake(meshID, convex, pos, rot, scale) if it has to be blittable.

Also - this fix can't come fast enough. Creating new Mesh instances just because we need to change the mesh is insane.

1 Like

There is only one thing i want for christmas, it's Physics.BakeMesh.

1 Like

Did anyone do this yet?