This was a quick revisitation of the SoftBodies project between Christmas and New Years, to reimplement it in a more recent version of NQAE, and to add a couple features that I had been thinking about. Notably, taking advantage of the fact that it is really only the points that move - when doing the rendering, my process has basically been to index into this list of the latest point locations to inform where the endpoints of the segments are, then drawing them.
The way I've implemented this is by regenerating the vertex buffers for the points, lines and triangles each frame. This is not the most efficient way to do it, if you think about the inherent redundancy that will come from uploading the sets of points multiple times. The better way to look at doing this is by just uploading the points each frame, and having static index buffers which tell the OpenGL primitives how to use the points for drawing. This way you upload only a single copy of the data each frame, and the lines and triangles which would otherwise use separate vertex buffers can basically just consist of indices into this list. I manually constructed the faces in Blender, similar to how I did the original model made only of segements.
One of the big things I added to this version of the program is the inclusion of faces in the model. I had thought a bit about this - again, since the points which define the model are the only thing that changes each frame, not the connectivity of the points, these can reference the point list in the same way that the lines do. Each frame, the list of indices doesn't change, only the point locations which the primitives will be drawn between.
I did some simple shading on the faces of the model, Phong specular and diffuse terms, and used FastNoise2 to generate the locations of the wheel and ground points. Some future directions might include another layer of dynamics between the ground and the wheel positions, so that they might leave the ground, or else get closer to the ground, as if by compression of a tire, or to even get into the modelling of tires and how they would deform with the weight which would be pressing down on them.
Multithreaded update is still a work in progress and may be something to return to - without the use of mutexes, I'm only able to make it work with a bunch of debug spew slowing each thread down enough to sync. That said, the update takes place in about 7us, so even the single threaded approach will scale to a radically larger model and maintain realtime performance. Another thing I want to try is doing this same type of operation on the GPU - this two-buffer approach, which holds the current and previous data as two separate sets of data will transfer to a GPU context nicely.
Last updated 5/15/2021