What is the main fork moving to? I know that XNA is dead and I am even tempted to move away from C# to straight DirectX with C++, but I am kind of attached to BEPU and the way physics behaves here.
I'll be pulling the dependency free version fork into the main branch. XNA support will stick around, but as another fork like SlimDX and SharpDX. All of the forks will switch to using a new renderer. Currently, the plan is to base the new demos renderer on either SharpDX or, for more cross platform support, MonoGame.
More information can be found
here.
To handle memory requirement, I started using InstancedMesh instead of StaticMesh. What are the performance implications of this? I know for a fact that RAM use is drastically reduced, but what about performance?
InstancedMeshes are a little slower because their acceleration structure is in local space. In order to find which triangles are near a potentially colliding object, that object must be pulled into the local space of the mesh and tested against the hierarchy rather than just directly using a world space hierarchy like the StaticMesh.
The cost of that transformation isn't zero, but it's fairly low compared to hierarchy traversal, contact generation, and boundary analysis.
There is one caveat to remember though: while it's tempting to throw instanced meshes every which way as they're nearly free in terms of memory, thousands of entries in the broad phase will slow things down a little bit eventually. Bundling them in StaticGroups can address this; instead of having 1000 entries in the broad phase, it would be just a single entry in the broad phase and then 1000 instanced meshes in a static group. This helps because the acceleration structures used by these shapes have more guarantees about functionality than the broad phase and can just skip a bunch of work.
Of course, it's always important to actually measure and test the performance to see what kind of boost you need and what kind of boost you get; the above are just high level rules of thumb.
how can you handle tens of thousands of physics enabled objects in a large sandbox game.
...
I have the world represented as rectangular chunks and I need some system to enable/disable physics for distant chunks. But I a robust way. I am afraid of having objects resting one on top of other and once you move far away, physics gets disabled, you come back, and you find things in different positions or even clipped into each other. And what about moving objects that have yet to settle at the point you cross the distance threshold and shut down the simulation for that chunk. Populating about 1/4 of the world with objects causes physics to take quite a bit.
This is a tricky problem because it generally involves implementing a 'meta' world on top of the physics world due to the efficiency constraints, and that's not a natural operation. It tends to involve discontinuities of some sort no matter how it's managed; it's just a matter of hiding those discontinuities most effectively. There's usually a nice big dollop of tedium involved.
Here's one possible model that could work well for some single player games:
1) Keep all static objects within the space so long as there exists dynamic objects near them.
2) Keep all active (i.e. not sleeping) dynamic objects in the space.
3) Keep all objects (static and dynamic) that are near the player in the space, even if sleeping.
After enforcing the above rules, you're left with a guarantee that whatever the player is interacting with is actually there, nothing will freeze mid-fall as the player moves away, and nothing will fall through the ground.
The next task is to figure out some heuristic that minimizes the cost of the simulation while guaranteeing the above 3 requirements. Trivially, the heuristic 'never remove anything from the space' satisfies the above, but is not particularly helpful for performance.
A better heuristic would be to examine dynamic objects outside of the interactive range of the player and check if they have gone to sleep yet (entity.ActivityInformation.IsActive). If they have, they can be removed.
However, entities do not go inactive in isolation. Their activity is determined by islands. An island is an interacting group of dynamic entities- the interactions can be contact points or constraints. If any one entity in the interaction island is active, the whole island is active.
So, you've got two choices if an inactive entity is found: remove it in isolation, or search out the whole island with a breadth first search through constraints or enumeration of all entities.
Removing the entity in isolation is certainly a lot simpler, but removing an entity wakes up the island that the entity belongs to. That's not good for a sleeping stack of objects- removing the bottom object would make the upper objects fall. You can fight this by manually setting the entity's former island's activity to false after removing the entity from the space. An entity's island is accessible in the entity.ActivityInformation.SimulationIsland property; it will go null once the entity is removed, though. Cache the object before entity removal and, if and only if the MemberCount (requires
development fork) of the island is greater than 1 prior to removal, immediately set the island's IsActive property to false after removing the entity.
Because the above analysis doesn't need to be performed instantly, you can spread it over multiple frames. Just checking a few hundred objects per frame would keep costs down. Using the 'remove whole island at once' approach would make things a little more expensive in the worst case, as you would have to finish finding the island.
A similar pass can be performed for static objects. Enumerating through static objects and checking if anything depends on them can be done by analyzing collision pairs or by performing broad phase queries to search for nearby entities. If there is nothing nearby, they can be safely removed.
As the player moves around, it will require that previously removed objects are added back to the simulation. In this case, reverse the process: plop all needed static objects in first, and then plop all dynamic objects back in. To avoid a sudden performance hit due to a bunch of new active simulation elements, it would be a good idea to immediately force all the newly added objects (which were previously removed due to inactivity) to inactive.
My preferred solution tends to be 'just make BEPUphysics faster.' A big part of one of our own projects is a fairly immense multiplayer simulation which is going to require some significant work in this direction, as detailed on the
version roadmap. There are limits to this approach, though
