Posts: 17
Threads: 9
Joined: Oct 2021
Reputation:
0
12-10-2021, 08:25 PM
(This post was last modified: 12-10-2021, 08:26 PM by netjeenpetje.)
Hi!
The skinned mesh renderer of the face of the character (animated with blend shapes) does not seem to bake a mesh collider (which I add in runtime using AddComponent).
The skinned mesh of the body's collider does bake, but only in a t-pose. This also is added in runtime.
Any idea how to make it work?
Regards
Posts: 6,321
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
12-10-2021, 10:33 PM
(This post was last modified: 12-10-2021, 10:34 PM by josemendez.)
(12-10-2021, 08:25 PM)netjeenpetje Wrote: Hi!
The skinned mesh renderer of the face of the character (animated with blend shapes) does not seem to bake a mesh collider (which I add in runtime using AddComponent).
The skinned mesh of the body's collider does bake, but only in a t-pose. This also is added in runtime.
Any idea how to make it work?
Regards
Not sure what you’re going for, but Unity does not support deformable MeshColliders (either skinned, or blend shaped). Baking it every frame like it seems you’re doing is not only really costly but will also behave very poorly, since no velocity information is contained in the mesh vertices a lot of tunneling issues will arise (objects, in this case fluid particles, passing trough the collider).
Can you give more details about your use case?
Posts: 17
Threads: 9
Joined: Oct 2021
Reputation:
0
(12-10-2021, 10:33 PM)josemendez Wrote: Not sure what you’re going for, but Unity does not support deformable MeshColliders (either skinned, or blend shaped). Baking it every frame like it seems you’re doing is not only really costly but will also behave very poorly, since no velocity information is contained in the mesh vertices a lot of tunneling issues will arise (objects, in this case fluid particles, passing trough the collider).
Can you give more details about your use case?
Hi,
We're trying to make the fluids collide with our animated VRoid models (UniVRM).
Regards,
Posts: 6,321
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
12-10-2021, 10:47 PM
(This post was last modified: 12-10-2021, 10:52 PM by josemendez.)
(12-10-2021, 10:37 PM)netjeenpetje Wrote: Hi,
We're trying to make the fluids collide with our animated VRoid models (UniVRM).
Regards,
No way you can do this using a single deforming MeshCollider for the entire body, that’s a very hacky approach. Use separate colliders (capsules, convex mesh colliders or distance fields) parented to the character’s bones. Both more robust, and much cheaper.
Note this applies to Obi as well as any physics in Unity.
Posts: 6,321
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
13-10-2021, 10:31 AM
(This post was last modified: 13-10-2021, 10:37 AM by josemendez.)
Following up the previous post (as I was in a bit of a hurry):
The whole point of MeshColliders is that they pre-process the mesh in order to allow for fast collision queries: when you first assign a mesh to the MeshCollider, all of its triangles are inserted into a spatial acceleration structure (BVH, BIH, Kd-tree, or similar, don't know Unity's implementation details). This is a costly operation but only done once, and it avoids having to brute-force test every triangle in the mesh for each collision query, every frame. Instead, this structure allows to quickly prune most of the triangles and test just a few of them for each query.
If you modify the mesh every frame then this pre-processing needs to happen every frame, which defeats its purpose: collision detection then becomes as costly, or even more, than the brute-force approach of testing all triangles all the time.
Furthermore, deforming the mesh also results in poor quality collision detection. This is because physics engines rely on CCD (continuous collision detection) for accurate collisions against moving objects, and CCD is often based on object velocities. Moving objects have a velocity, that tells the engine where they're about to move. This allows the physics engine to predict movement.
But when you change mesh vertex positions around, you're essentially "teleporting" them: vertices have no velocity of their own. The engine has no way to know where vertices are going to move next, so it can't accurately collide against triangles: only if a triangle overlaps an object (in Obi's case, a fluid particle) a collision will be registered. Triangles are infinitely thin, and fluid particles are very small, so the chance they just pass trough each other is really high: virtually no collisions will take place.
That's why attempting to deform a MeshCollider is a bad idea, both from performance and robustness standpoints.
Posts: 17
Threads: 9
Joined: Oct 2021
Reputation:
0
(13-10-2021, 10:31 AM)josemendez Wrote: Following up the previous post (as I was in a bit of a hurry):
The whole point of MeshColliders is that they pre-process the mesh in order to allow for fast collision queries: when you first assign a mesh to the MeshCollider, all of its triangles are inserted into a spatial acceleration structure (BVH, BIH, Kd-tree, or similar, don't know Unity's implementation details). This is a costly operation but only done once, and it avoids having to brute-force test every triangle in the mesh for each collision query, every frame. Instead, this structure allows to quickly prune most of the triangles and test just a few of them for each query.
If you modify the mesh every frame then this pre-processing needs to happen every frame, which defeats its purpose: collision detection then becomes as costly, or even more, than the brute-force approach of testing all triangles all the time.
Furthermore, deforming the mesh also results in poor quality collision detection. This is because physics engines rely on CCD (continuous collision detection) for accurate collisions against moving objects, and CCD is often based on object velocities. Moving objects have a velocity, that tells the engine where they're about to move. This allows the physics engine to predict movement.
But when you change mesh vertex positions around, you're essentially "teleporting" them: vertices have no velocity of their own. The engine has no way to know where vertices are going to move next, so it can't accurately collide against triangles: only if a triangle overlaps an object (in Obi's case, a fluid particle) a collision will be registered. Triangles are infinitely thin, and fluid particles are very small, so the chance they just pass trough each other is really high: virtually no collisions will take place.
That's why attempting to deform a MeshCollider is a bad idea, both from performance and robustness standpoints.
Thanks for your expertise. Which method would you use? We have a system that allows users to import models, so we can't cover the body and face with shapes for collision.
Thanks in advance for the help!
Posts: 6,321
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
14-10-2021, 10:48 AM
(This post was last modified: 14-10-2021, 10:58 AM by josemendez.)
(14-10-2021, 10:39 AM)netjeenpetje Wrote: Which method would you use? We have a system that allows users to import models, so we can't cover the body and face with shapes for collision.
I'd place colliders at the character's bones, that's the tried and tested method that has been used throughout the gaming industry for years. It's simple, cheap, and robust.
Nothing stops you from placing colliders at the bones, regardless of where or how you've imported your models. (as long as your model uses skeletal animation, of course!). If the user can import custom models, just pre-segment the mesh into multiple separate MeshColliders (one per bone) at import time. This can easily be done by checking skin weights to determine which bone has the most influence over each mesh triangle.
You can do that if you want a fully automatic system, or you can require users to place collision meshes on their models themselves. This is not uncommon among applications/games that allow users to import custom avatars.
|