Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Not realtime simulation without affecting FPS
#1
Is there a way to do not-real-time simulation in the background without affecting FPS? 

I need to do a complex simulation with lots of substeps with high poly meshes and this affects fps. So I am going to show some progress bar and do simulation in the background.

Is this possible somehow? 

I need this for Cloth and Soft Body simulation.
Reply
#2
(21-08-2018, 11:39 AM)mmortall Wrote: Is there a way to do not-real-time simulation in the background without affecting FPS? 

I need to do a complex simulation with lots of substeps with high poly meshes and this affects fps. So I am going to show some progress bar and do simulation in the background.

Is this possible somehow? 

I need this for Cloth and Soft Body simulation.

Not unless you're willing to use threads. A simulation step cannot be chopped up in pieces. It must be run in a single go, so running it on a thread other than the main thread is the only option.

solver.SimulateStep() sends all simulation tasks to a threadpool and puts the calling thread to sleep until all tasks have been completed. You could call solver.SimulateStep() on a thread other than Unity's main thread. That would allow the main thread to continue updating stuff while this other thread waits for Obi to complete the step.

Also note that neither Obi or Unity are designed to do this. Unity expects physics simulation to be completed during FixedUpdate(), and it will not go on with the frame until FixedUpdate() has ended. So two-way interaction with rigidbodies would not work if you simulate outside of Unity's stablished update cycle. You should also keep in mind that many Unity methods/classes cannot be used outside of the main thread, so issues might arise with this.

Another, much cheaper option that might work for you is using Unity's captureFramerate: (https://docs.unity3d.com/ScriptReference...erate.html). This allows you to decouple game time from real time.
Reply
#3
(21-08-2018, 12:54 PM)josemendez Wrote: Not unless you're willing to use threads. A simulation step cannot be chopped up in pieces. It must be run in a single go, so running it on a thread other than the main thread is the only option.

solver.SimulateStep() sends all simulation tasks to a threadpool and puts the calling thread to sleep until all tasks have been completed. You could call solver.SimulateStep() on a thread other than Unity's main thread. That would allow the main thread to continue updating stuff while this other thread waits for Obi to complete the step.

Also note that neither Obi or Unity are designed to do this. Unity expects physics simulation to be completed during FixedUpdate(), and it will not go on with the frame until FixedUpdate() has ended. So two-way interaction with rigidbodies would not work if you simulate outside of Unity's stablished update cycle. You should also keep in mind that many Unity methods/classes cannot be used outside of the main thread, so issues might arise with this.

Another, much cheaper option that might work for you is using Unity's captureFramerate: (https://docs.unity3d.com/ScriptReference...erate.html). This allows you to decouple game time from real time.

Thanks for help.

So even if I call solver.SimulateStep() from other thread internally it will call Unity API, so this leads to crash or exception because Unity not allowing to call its API from separate thread. 
I thought you are transferring Untiy colliders data into your native solver code which probably running in the separate thread already. So why to use unity API if you do the whole simulation and collision detection by yourself in native code? So you have a whole physical world decoupled from Unity aren't you? Or maybe I am wrong. Could you clarify?

Regarding captureFramerate as I understand it basicaly slows down the whole game. But I need to game runs normally, only slow down the simulation.
Reply
#4
(21-08-2018, 03:13 PM)mmortall Wrote: Thanks for help.

So even if I call solver.SimulateStep() from other thread internally it will call Unity API, so this leads to crash or exception because Unity not allowing to call its API from separate thread. 
I thought you are transferring Untiy colliders data into your native solver code which probably running in the separate thread already. So why to use unity API if you do the whole simulation and collision detection by yourself in native code? So you have a whole physical world decoupled from Unity aren't you? Or maybe I am wrong. Could you clarify?

Regarding captureFramerate as I understand it basicaly slows down the whole game. But I need to game runs normally, only slow down the simulation.

We do have a minimal internal representation of all colliders/rigidbodies in the scene, but we do not simulate them. Only particles are simulated by our engine. We need to use Unity's API in order to:

1.- Get collider data so that we can accurately represent these in our internal physics engine, to generate contacts between particles and colliders.
2.- Once particle-collider contacts are solved, Inject forces back to rigidbodies for two-way coupling. The rigidbodies and colliders are still fully simulated by Unity.

As a result, we do not override Unity's physics engine. Each step we merely extract the info we need about colliders in order to be able to generate particle-collider contacts, and then apply forces back to them. Both steps need to use Unity's API. It's the only way to do it.

Thinking about it, you could strip two-way interaction and all rigidbody related code from Obi (in case you do not need it, but if you do then you're stuck as it has to happen at a very specific point of Unity's update cycle), move collider data retrieval to the main thread and do it periodically. Imho this begins to look like a major rewrite of the system and I'm not even sure it would be possible. I guess Unity is just not designed to decouple physics and rendering the way you need to.
Reply