Eureka! Finally success! Boulder support is done and I actually have a fairly decent generic static clutter system for the map.
I write posts in two ways: one has a plan and a script, the other is a journal styled affair. This is what I used for these posts related to boulders. I just developed and took (mental) notes of interesting progress or observations, together with screenshots at key moments. After a while I gathered these notes and wrote a post about the progress in chronological order. Only since last post (posts sometimes have a delay, so when I say today it was probably yesterday when the events happened) I kind of forgot what most of the screenshots were for.
So today I'll be presenting the abridged version.
I did another step of optimization towards reducing RAM and improving the terrain pool manager.
I also implemented instanced physics. BEPUPhysics actually has support for this, but on top of XNA and BEPU I have my own engine and structures that couldn't handle instancing. Updating this required a minor rewrite of data structures and since I was kind of in a hurry, the rewrite comes with a caveat: you can't use instancing with composite meshes! Luckily boulders are simple one-piece meshes. In the future I'll improve the system to handle any meshes.
Putting the two together we get this:
We have the normal 4 square kilometer map with the old view distance and 10061 objects, yet the memory use is only 112/107/469! Fantastic progress! To think that a few days ago I couldn't fit a few hundred boulders! Grass is still offline because I didn't get to refactor it for streaming/low memory use. And I hate my current implementation, so one day I'll rewrite it.
The only problem is the performance. I am getting only around 26 FPS. Physics time is high and also a ton of objects are actually rendered.
Time to solve both!
I start implementing a very simple spatial division scheme based on the clunking of the terrain. Using this both frustum culling and distance checks are simplified. This was more complicated than it seems now writing about it, but:
Framerate is up to 40 and rendered objects is way down. I only render a fixed distance in front of the camera, but this distance is variable for different kinds of entities: terrain has a larger distance, boulders a smaller one, grass even shorter.
So now that rendering and spatial partitioning is fixed, let's do something about the physics time. For this we enable the new view distance and also increase the number of boulders to cover the map corner to corner:
I still need to tweak the view distance, but it is improved, thus consuming more resources. RAM use is up to 154/119/608, but we do have 17119 physics enabled objects, 590 being currently rendered in that shot.
To fix physics, I do two things. The boulders are not very detailed, but still a little bit high for physics. I want accurate physics, but this is probably too much. Take a look at the complexity and small terraces that the boulder has:
I implement collision meshes, making it so that a mesh can have a collision mesh that is not identical to its graphical representation. Because instanced physics supports only simple meshes, the limitation is in place for collision meshes too. I try and simplify the boulder mesh, while still keeping the general shape. I don't do a great job, but I'm an engine programmer, not a modeler:
Collision meshes are anyway optional, so when a very precise shape is needed, just don't use them. Or hire a modeler! Still, this shape is good enough for physics interaction:
The next step is to group up all those boulders into some larger entities, similar to the spatial partitioning scheme I use, thus greatly reducing the search space. At first this works horrible, performing poorly and eating up all the RAM.
So I decide to take a break.
I add support for placing meshes in such a way on terrain that they have a natural orientation taking into consideration the slope.
I start to investigate an ancient and very serious bug in the terrain access methods. I call it a day before finding the bug.
But the next day, with fresh forces, I fix the bug, implement physics grouping and get the girl!
Here is a screenshot:
We have 40 FPS, with negligible physics time, almost 1400 of of the 17000+ objects rendered and memory consumption up to norm! This on an Intel HD integrated GPU. BEPUphysics is a beast!
Just as planned! I'll be taking a small break, but next time we add a few new clutter objects, hopefully trees, columns and another boulder type.