Norbo wrote:Did you happen to run into any significant issues when it came to plugging the cube terrain collidable into the engine?
No actually it was relatively pain-free especially since the terrain implementation already took care of the majority of the framework pointing out what I had to plug to get it functioning properly. It was mostly a matter of translating the assumptions made in the terrain to work in all dimensions.
I'd probably say the biggest effort was put into getting an efficient GetOverlaps() implementation going. The final idea I used was to "reverse project" the incoming bounding box from the curved space above each face to a flat space defined by the face's coordinates before extracting the min/max verts from the shape's data set. It worked out pretty nicely and I added a debug draw callback into the function to verify the set of verts that were being hit during each collision. The one hack I had to add in the end was to grow the incoming bounding box by one unit in each direction and to this day, I don't know why that is the case.
The other function I spent a bit of time on was the RayCast function because it's fairly tough to shoot a ray in any given direction and get an accurate hit on a displaced sphere. While you can easily get up to the sphere's boundaries, (and unless I'm missing a known algorithm) from that point on, it comes down to ray marching (be it in pre-calculated steps - like cone stepping - or constant steps). All in all, I think I have it returning down to 0.0000001 accurate results within 20-50 height queries on the surface lookups. I'm thinking I could look into doing a full cell step which is similar to the way the terrain raycast works to further optimize the lookup, but we don't rely on it too much to warrant further optimizations right now. Of course I have the obvious optimization where I return the result in one shot if the ray is cast directly to the origin on the cube terrain which happens when an object requests its "altitude".
Last but not least, the function I had a bit more trouble than I thought was going to have is the ProcessCandidates() function where it checks to see if the object is inside the cube terrain and pushes it out if necessary. After a long time fiddling, optimizing etc, it finally hit me that the normal of the contact was the inverse of what I thought it was supposed to be
But again the cool part is that it's a one shot call to see if the given object is inside the terrain.
Down the line, depending on how crazy we get with the number of physics related elements in the game, I'm thinking that I could probably keep optimizing the GetOverlaps() function and potentially special case it for certain primitive types if need be, but so far I haven't had to do it.
At first, I was hoping that I was going to be able to implement my custom collidable in a "plug-in"-like separate csproj, but after going a tiny bit into it, I realized that it wasn't going to work as I had expected because the API is expecting that collidables are compiled in and much of the functionality is tagged as "internal" keeping external libs from accessing them. Definitely a good thing for an end user who doesn't want to have to shuffle through things they are not really meant to see unless he's adding new features to the engine, and also probably good for speed purposes as the compiler can be more liberal about certain things when the given interface is not public.
Phew that was a long post!