Hi Norbo,
I am delighted with Bepu and the way it is designed! I'm doing physics with thousands of connected pieces and ran into some performance snags that I mentioned earlier. You may be pleased to know that I have managed to develop some quite effective work-arounds to my earlier performance problems. I took advantage of the fact that large islands are the problem. It's an order of magnitude problem. By doing some sneaky on-the-fly conversions between dynamic and kinetic, I am able to break the huge islands down into smaller islands that take far less time to process. This method is actually working better than I had expected.
I do have two remaining problems though, that I am hoping that you can assist me with.
1) Most of the simulation runs fine at 20Hz which provides a good balance between CPU utilization and appearance. However, the rendering system is running at 60FPS so a few fast-moving objects are not getting their locations updated often enough for smooth movement. I would like to be able to run a super-fast physics pass where only the specified list of objects have their locations updated.
2) Is there some way to change an object from kinetic to dynamic after a collision has been detected, but before forces have been applied? I'd like to be able to convert them instantaneously rather than in the next frame.
Dynamic kinetics
Re: Dynamic kinetics
That's good to hear! The mode switching is an interesting approach.
When the time is 'in between' updates, the engine very quickly interpolates the buffered properties (centerPosition, orientationMatrix, worldTransform, and a couple of others) between the previous physics frame's value and the current frame's value. This allows the motion to appear fluid even when the physics engine is updating at a very low rate.
Switching from kinematic to dynamic and vice versa requires some reinitialization that takes out a lock that is contested by the update method itself. If the immediate event handler that does the reinitialization is called from another thread than the main thread (as would happen in a multithreaded simulation), it should deadlock. There might be some event management that would throw an unrelated exception in single threaded code, too. In summary, it's not exactly a supported operation while the space is updating
As part of the upcoming 'modularization' of the architecture, I plan to have much more visible stages and places to hook into that would make this easier.
Enabling space.simulationSettings.timeStep.useInternalTimeStepping with the associated timeStepDuration set to 1/20f should do what you want. When useInternalTimeStep is on, each update accumulates the time since the previous update. Only if it goes over the timeStepDuration does it execute an actual physics update (and it will do more than one if necessary).I would like to be able to run a super-fast physics pass where only the specified list of objects have their locations updated.
When the time is 'in between' updates, the engine very quickly interpolates the buffered properties (centerPosition, orientationMatrix, worldTransform, and a couple of others) between the previous physics frame's value and the current frame's value. This allows the motion to appear fluid even when the physics engine is updating at a very low rate.
It doesn't look like there's a good safe spot to stick that right now. The engine immediately jumps from narrow phase collision detection to velocity solving without an intermediate updateable stage. You could use "Immediate" suffixed events, but it would probably fail.2) Is there some way to change an object from kinetic to dynamic after a collision has been detected, but before forces have been applied? I'd like to be able to convert them instantaneously rather than in the next frame.
Switching from kinematic to dynamic and vice versa requires some reinitialization that takes out a lock that is contested by the update method itself. If the immediate event handler that does the reinitialization is called from another thread than the main thread (as would happen in a multithreaded simulation), it should deadlock. There might be some event management that would throw an unrelated exception in single threaded code, too. In summary, it's not exactly a supported operation while the space is updating
As part of the upcoming 'modularization' of the architecture, I plan to have much more visible stages and places to hook into that would make this easier.
Re: Dynamic kinetics
I may be using useInternalTimeStepping incorrectly. Every time I've tried it out it has killed performance *dramatically*. It seems to take a good 5-10 times as long to process each loop. Any ideas?Norbo wrote:Enabling space.simulationSettings.timeStep.useInternalTimeStepping with the associated timeStepDuration set to 1/20f should do what you want.
That sounds like an awesome feature. I'll put some more testing time into it. That certainly may solve my problem!Norbo wrote:When the time is 'in between' updates, the engine very quickly interpolates the buffered properties (centerPosition, orientationMatrix, worldTransform, and a couple of others) between the previous physics frame's value and the current frame's value. This allows the motion to appear fluid even when the physics engine is updating at a very low rate.
I did try EventHandlerInitialCollisionDetectedImmediate already and it did not have the desired effect. At this point though, I'm very willing to look into any other possible work-arounds. I've thought about doing some projections using a second entity that will do collision detection against where the object will be based on the object's current velocity.Norbo wrote:Switching from kinematic to dynamic and vice versa requires some reinitialization that takes out a lock that is contested by the update method itself. If the immediate event handler that does the reinitialization is called from another thread than the main thread (as would happen in a multithreaded simulation), it should deadlock. There might be some event management that would throw an unrelated exception in single threaded code, too. In summary, it's not exactly a supported operation while the space is updating
As part of the upcoming 'modularization' of the architecture, I plan to have much more visible stages and places to hook into that would make this easier.
Re: Dynamic kinetics
Assuming the engine can keep up with what is being asked of it and the times being passed into space.update are correct, it should perform the same. The issue comes when the update gets itself into a vicious loop. If it has to do a massive update, it will take a while which in turn lengthens the time until the next update. In the next update, it still has a big job, but since the previous update took so long, now it might have to do two or more updates to catch up to gametime. Then, its even further behind... and so on.I may be using useInternalTimeStepping incorrectly. Every time I've tried it out it has killed performance *dramatically*. It seems to take a good 5-10 times as long to process each loop. Any ideas?
You can stop that behavior by setting space.simulationSettings.timeStep.timeStepCountPerFrameMaximum to a lower number, even 1. In the 'vicious cycle' example above, it would basically give up trying to match real time and simulate as well as it can.
I don't fully understand the exact circumstances under which the switch is taking place; I might be able to offer some fancy tricks if I understand the situation better.I did try EventHandlerInitialCollisionDetectedImmediate already and it did not have the desired effect. At this point though, I'm very willing to look into any other possible work-arounds. I've thought about doing some projections using a second entity that will do collision detection against where the object will be based on the object's current velocity.