Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Offline Rendering] update Mesh Colliders
#1
Hi, I've been using Obi Fluid since many month now, it's an awesome asset and I love it.

Recently, I started a project and I attempt to build an environment in Unity to do Offline Rendering to animate sequences.

For the scenes with fluids, I found that the Obi Fluid solution is absolutly perfect.
I've succedded in making a really simple script to bake a mesh collider that updates every frames. 

Code:
Mesh colliderMesh = new Mesh();
       meshRenderer.BakeMesh(colliderMesh);
       Mcollider.sharedMesh = null;
       Mcollider.sharedMesh = colliderMesh;

[Image: AVS9ZdR.gif]

here's the result. (the model is from Rascal asset but there's absolutly no connection with the current problem)

As you can see, the Obi collider component attached to the object with the Mesh Collider does not updates the collisions with the fluid.

Is there any way I should be able to make it consider the updated mesh ? 
(Keep in mind it's for an Offline solution, so computation time is not really an issue here)

thanks !

[EDIT]


I finally found a quick solution wich give this result : 
https://imgur.com/a/tH66fwz

To do this, I simply modified the Obi Collider script, including an Update() function wich contained two things : 

- Getting the Mesh Collider component mesh
- Setting it as the current Source Collider.

Last question : it is possible to get informations when a particle collide on a surface ? 
Like to trigger an action (I would like to apply a decal to the collided object to simulate a wet surface)
Reply
#2
(08-05-2020, 07:42 PM)kouglov Wrote: Last question : it is possible to get informations when a particle collide on a surface ? 
Like to trigger an action (I would like to apply a decal to the collided object to simulate a wet surface)

Hi there!

Yes, you can get a list of all contacts generated each frame. To do that, subscribe to the solver's OnCollision event. See:
http://obi.virtualmethodstudio.com/tutor...sions.html
Reply
#3
(08-05-2020, 07:42 PM)kouglov Wrote: To do this, I simply modified the Obi Collider script, including an Update() function wich contained two things : 

- Getting the Mesh Collider component mesh
- Setting it as the current Source Collider.
Hi everyone,

Sorry to post in this old thread, but about modifying the ObiCollider script, can someone give the the exact code section for this purpose?
Reply
#4
(20-02-2022, 06:17 AM)hawk94 Wrote: Hi everyone,

Sorry to post in this old thread, but about modifying the ObiCollider script, can someone give the the exact code section for this purpose?
I hope the admin of this forum or any expert  programming can help me. This is a very interesting effect, right?
I heard it cost some memory of Unity to do this, but we can just start and then find some way to optimize the code.
If we can not modify Obicollider like this, how can we use Obi fluid to simulate a person swimming or walking in the water?
Reply
#5
(24-02-2022, 12:04 PM)hawk94 Wrote: I hope the admin of this forum or any expert  programming can help me. This is a very interesting effect, right?
I heard it cost some memory of Unity to do this, but we can just start and then find some way to optimize the code.
If we can not modify Obicollider like this, how can we use Obi fluid to simulate a person swimming or walking in the water?

Hi there!

It's been discussed tons of times in this forum: modifying a MeshCollider at runtime is a terrible, terrible idea for many reasons. Performance is one of them (since you force the data structure used to speed up collision queries to updated every frame. This is usually a BVH or a BIH, so quite costly), but not the main reason you should avoid this.

The main reason why this should be avoided is that it fails to detect collisions with small-ish objects 99% of the time. This happens because concave meshes are hollow: only the triangles at their surface will collide with things. They're like empty shells: they have no volume, so if any object gets inside the collider, it will stay inside the collider instead of being projected back out. If the triangles in the mesh are rigid and don't move relative to each other, CCD (continuous collision detection) can kick in and approximate the velocity of each triangle to avoid tunneling.

This mechanism goes out the window the moment you move triangles around: you're basically teleporting mesh vertices from one frame to the next, so the engine has no way of predicting collisions unless a particle happens to intersect a triangle. Particles are extremely small and triangles are infinitely thin, so the chances of a collision being detected are basically zero. Most particles (or any other small objects) will pass right trough the mesh collider.

Wrapping up: updating mesh collider at runtime --> extremely costly and brittle collision detection. I don't recommend doing it unless you're 110% sure of what you're doing, why, and how. OP wanted to do this for an offline animation (not realtime) so he can just reduce the timestep to a extremely small value until collisions work well enough. In a game, this is not an option as it would obliterate performance.

Quote:If we can not modify Obicollider like this, how can we use Obi fluid to simulate a person swimming or walking in the water?

Assuming you could simulate a large enough body of water for a person to swim in it (and using particles, you can't), you would do this the way it's been done in games for ages: approximate the person using convex colliders. Usually this means capsules parented to its joints, but if you wish for more accurate shapes you could use distance fields.

As a rule of thumb: in any game, MeshColliders -or their equivalent in other engines- should only be used for static environments. Any other object (specially dynamic ones) must be approximated as compound convex or primitive colliders. This is the reason Unity doesn't support deformable MeshColliders out of the box and you must use hacks/workarounds if you want one: deformable MeshColliders aren't supposed to exist at all.

let me know if I can be of further help. cheers!
Reply
#6
(24-02-2022, 12:29 PM)josemendez Wrote: Wrapping up: updating mesh collider at runtime --> extremely costly and brittle collision detection. I don't recommend doing it unless you're 110% sure of what you're doing, why, and how. OP wanted to do this for an offline animation (not realtime) so he can just reduce the timestep to a extremely small value until collisions work well enough. In a game, this is not an option as it would obliterate performance.
Thank you very much for your explanation.

I've done some search on Unity and heard  that the deformed mesh collider update really consumes much of computer resource.

Therefore I decide to switch to offline rendering and with slow motion effect. My intention now is to make a short introduction clip with slow motion effect.
I have learned to use the Time.timescale in script to make Unity run in slow motion effect. I tested many particles collide on a static high resolution mesh. Without the Time.timescale script, particle collision nearly crashes my Unity. However with the timescale set to 0.2, everything becomes ok. Moreover, decimating the mesh to 30% resolution makes the collision render smoother.

So could you please help me with modifying the ObiCollider script to update skin mesh collider?
Reply
#7
(03-03-2022, 12:51 PM)hawk94 Wrote: Thank you very much for your explanation.

I've done some search on Unity and heard  that the deformed mesh collider update really consumes much of computer resource.

Therefore I decide to switch to offline rendering and with slow motion effect. My intention now is to make a short introduction clip with slow motion effect.
I have learned to use the Time.timescale in script to make Unity run in slow motion effect. I tested many particles collide on a static high resolution mesh. Without the Time.timescale script, particle collision nearly crashes my Unity. However with the timescale set to 0.2, everything becomes ok. Moreover, decimating the mesh to 30% resolution makes the collision render smoother.

So could you please help me with modifying the ObiCollider script to update skin mesh collider?

There's no need to modify the ObiCollider script in any way. You simply call UpdateMeshData() on the tracker:

Code:
(collider.Tracker as ObiMeshShapeTracker).UpdateMeshData();

Check the API docs for details.
Reply
#8
(08-05-2020, 07:42 PM)kouglov Wrote: Hi, I've been using Obi Fluid since many month now, it's an awesome asset and I love it.

Recently, I started a project and I attempt to build an environment in Unity to do Offline Rendering to animate sequences.

For the scenes with fluids, I found that the Obi Fluid solution is absolutly perfect.
I've succedded in making a really simple script to bake a mesh collider that updates every frames. 

Code:
Mesh colliderMesh = new Mesh();
       meshRenderer.BakeMesh(colliderMesh);
       Mcollider.sharedMesh = null;
       Mcollider.sharedMesh = colliderMesh;

[Image: AVS9ZdR.gif]

here's the result. (the model is from Rascal asset but there's absolutly no connection with the current problem)

As you can see, the Obi collider component attached to the object with the Mesh Collider does not updates the collisions with the fluid.

Is there any way I should be able to make it consider the updated mesh ? 
(Keep in mind it's for an Offline solution, so computation time is not really an issue here)

thanks !

[EDIT]


I finally found a quick solution wich give this result : 
https://imgur.com/a/tH66fwz

To do this, I simply modified the Obi Collider script, including an Update() function wich contained two things : 

- Getting the Mesh Collider component mesh
- Setting it as the current Source Collider.

Last question : it is possible to get informations when a particle collide on a surface ? 
Like to trigger an action (I would like to apply a decal to the collided object to simulate a wet surface)

Hello! im new here, can you please share snippet of code you made for this decision? thank you
Reply