Discussion Modeling Boats, Ships, and Other Watercraft in Orbiter? Experiments with Hydrostatics and the Touchdown Model

I'm not really at the point where I want a big complex hull. Something smaller that I can manipulate a little easier would be better for development purposes. If I could get an Orbiter mesh of something like a row boat or a similarly simple hull, I would like to see if I can calculate proper normals to the triangles and (perhaps) make a more accurate, generalizable buoyancy model.

The Benchy model is fun, but it's a single mesh group, where I really would like to focus on the hull bits. If the buoyancy of the wheelhouse becomes important, something went terribly wrong.
 
So I attempted a couple methods to directly model buoyancy on surface vessel hulls, but they are computationally very challenging and cost a lot a framerate.

I figured out how to get the depth of exterior hull vertices in local coordinates using the vessel altitude and rotating from vessel coordinates to relative coordinates through pitch, roll, and yaw. That allows the pressure distribution on a surface to be determined, but things get ugly after that, particularly if the surface is semi-submerged. To integrate buoyant forces on the hull, you need to determine the net hydrostatic load and locate it at the center of pressure of only the submerged part of all the surfaces. This is possible but complicated to do in general. Even if this were done, this would produce a force vector on each surface where the magnitude AND location changes dynamically, and can change rather quickly, which quickly would punt you into space.

I also tried a point cloud method to integrate the volume and centroid of the submerged portions of the vessel in order to use Archimede's principle to determine the net buoyant force and its line of action. This works after a fashion, but even for a simple box it is very computationally expensive as you must perform this integration every time step, and in order to get accurate results you must count lots of points. Due to the granular nature of this model, you tend to get step changes in buoyant force as more points emerge/submerge, and again this causes fits with the propagators. Numerical underrelaxation helps somewhat with stability, but it causes the application of force to lag from the current state of the vessel, so too much underrelaxation leads to different instabilities. There really is no setting where the simulation is stable. The only way to "fix" this is to greatly increase the number of points in the point cloud, but that is murder on frame rate.

Could you adapt one or both of these methods to something where a shader pipeline on the GPU renders hydrostatic forces on the mesh to a texture? It would basically just be "color the texture according to the Z-coordinate of each pixel", and then the direction of the force would just be normal to the mesh at each point, which AFAIK is one of the things that a GPU needs to be able to calculate well (I'm not really a graphics guy, but the term "surface normal" keeps popping up in things I read about graphics).

I got a box that jumped in and out of the surface like a caffeinated dolphin which was amusing but far from correct. I have a video of it but I am refraining from posting it as I don't want to impose the storage on OF.

This forum's memories go back even to the Elder Days. Use a low-res GIF, for old time's sake?
 
It occurs to me that my Zorb might be an excellent test bed for buoyancy modeling. Reasonable, but not excessive hull resolution, and testing should be relatively easy (if the density of the ball is half that of water, it should float exactly half out of the water, shouldn't be accelerated laterally, etc..).

I would need to write a function that takes the mesh, determines the normal of each triangle (not the vertex normals used for shading, the actual mathematical-normal-to-a-plane-made-by-three-points normals), and get the centroid location and area of each triangle. Then just need to run a rotational transformation from vessel to local coordinates, figure out which centroids are at negative altitude, calculate the hydrostatic pressure at that negative altitude (depth), multiply by the triangle area, and apply the force in the direction of the normal vector.

Easy peasy.
 
I had a simple boat:
Sadly, I didn't save it, but I could try to repeat and make something similar if needed (but it might be ready in about a day).
 
I had a simple boat:
Sadly, I didn't save it, but I could try to repeat and make something similar if needed (but it might be ready in about a day).
Thanks for that, but I would wait for now. I'll see if I can get code to work on my Zorb which is a simpler test case.
 
So I am calculating the hydrostatic pressure on all submerged vertices, integrating the normal pressure distributions on the related triangles, and summing the pressure forces on each triangle and applying them with a single instance of add_force. A sphere with 50% of the density of water floats halfway out, as expected:

Screenshot at 2024-11-18 22-52-53.png
The math isn't horrible. You need to determine all of the triangle areas, normals, and centroids once at the start of the session. You need to rotate the vertex coordinates into local horizontal coordinates using pitch and bank angles, then test to see which ones are under the surface. But the force magnitude is easy to calculate and just needs to be multiplied by the triangle unit normal to give it direction. I am adding all of the force vectors and applying them with one instance of add_force. I can do this with a sphere as all the pressure forces act through {0,0,0}. For a more general hull shape I would have to determine both the net force and moment on the hull at each time step.

I technically should apply the hydrostatic forces at the center of pressure of each triangle, not at each triangle centroid. But the deeper the triangle goes the closer the center of pressure becomes to that centroid, and if the number of triangles is high enough the difference becomes negligible. I'm currently only calculating forces on completely submerged triangles, which neglects the triangles near the waterline. But the hydrostatic forces on those triangles are small, and if the hull is vertical the force isn't really opposing the weight of the vessel, so it might not be worth the effort to program the edge cases (I might still do so, because madness).

One nuisance is that I still must set some touchdown points, otherwise Orbiter lifts the entire mesh out of the surface and hovers it. I set the minimum of three touchdown points and made their stiffness very, very low, so the touchdown point forces are negligible and don't overwhelm the calculated pressure forces.
 
For a boat, there should be a free 3d model of the Titanic out there on the internet...















... it should work fine, as there are no icebergs in the Orbiter. :rolleyes:
 
Doesn't your bouyancy model work with an iceberg? :cool:
 
Doesn't your bouyancy model work with an iceberg? :cool:
Yes. It could actually be an interesting test as the net positive buoyancy is much lower.

That's a nuisance; oapi.dbg_out() doesn't seem to want to give output to the screen anymore for some reason. I need to see my numbers. Grr...
 
Titanic is exactly a ship I'd like to make a mesh for in the future :)
 
Yes. It could actually be an interesting test as the net positive buoyancy is much lower.

That's a nuisance; oapi.dbg_out() doesn't seem to want to give output to the screen anymore for some reason. I need to see my numbers. Grr...
you can sprintf at oapiDebugString()
 
you can sprintf at oapiDebugString()
I'll have to see if there is a Lua equivalent for that. Apparently oapi.dbg_out() only works in full screen mode. I don't know why that would be, but I have it working again.
 
Now I am integrating the pressure distribution and am applying the force to a center of pressure position calculated on all submerged triangles. Unfortunately this requires a separate instance of add_force for every single submerged triangle face, but it still works nicely even for over 100 triangles. However, this should permit accurate hydrostatic forces to be calculated for even relatively coarse hull meshes.

Currently I am only applying forces to triangles that are fully submerged. I will need to work on the special cases of triangles at the waterline where only one or two of the vertices are submerged. Again, for a high poly hull this probably won't be noticeable, but modeling these special cases should permit coarser meshes to be used and still get accurate hydrostatic forces with fewer add_force instances.
 
Trying to update the code to apply the model only to specific mesh groups. For ships it really only needs to be applied to the main hull.
 
Doing some experimenting, if I set the density of the Zorb to 500 kg/m3 (half that of water), it seems that it comes to rest at an average depth of 1-2 cm (relative to the Zorb diameter of 3 m). It should technically rest at 0 m (center of Zorb should be at water level). I think the small discrepancy is due to the fact that I am only calculating forces on fully submerged triangles and am neglecting the partially submerged triangles at the waterline, which can contribute a small amount of buoyancy. At this condition It will pitch and roll slowly as slight imbalances in the hydrostatic forces will cause some small torques on the vessel, and it isn't particularly stable as the center of mass is very close to the center of pressure of the Zorb.

If I set the Zorb density greater than 500 kg/m3 and less than 1000 kg/m3, the center of mass of the Zorb is lower than the center of pressure on the Zorb, and it floats and remains level, exhibiting appropriate stability.

I found that even setting the touchdown point stiffness very low seemed to cause some spurious forces that would move the Zorb laterally if the surface was anything other than perfectly flat, so I set both the stiffness and damping values for the touchdown points to 0 so they wouldn't interfere.

I've updated my code to calculate hydrostatic forces on triangles only on particular mesh groups, so I can apply the model to appropriate hull surfaces vs. the entire mesh.

I think I want to get to work on the special cases where the triangles may be partially submerged and see if that allows the 50% density condition to rest at 0 m elevation. After that, I think making a very crude hull would be in order, perhaps I can get a low poly box to float sensibly even with relatively few triangles. That would be a very challenging test for the center of pressure calculations.
 
So I did a little test to see how well the hydrostatic model could handle splashdown. I took the Zorb MOOSE scenario (uses my Zorb as a proxy for the MOOSE escape system) and deorbited it over the Pacific:

Screenshot at 2024-11-21 17-01-56.png

Came down off the coast of Baja just after dawn:

Screenshot at 2024-11-21 17-04-11.png

Hit the water going about 120 m/s (no parachute). It went down really deep, but eventually slowed and bobbed back up to the surface:

Screenshot at 2024-11-21 17-08-30.png
 
Back
Top