RVO 3d with planar Obstacles and submarine steering

I’m trying to build a match 3 game that involves adding fish to a fish tank. I need avoidance and fish like movement so I thought I might share a way of doing it and the results. It works better than I expected.

The public domain RVO2 3D does not support planar obstacles so I decided to implement my own. The planar obstacles are harder because you are not just avoiding a point, but lines and planes as well (the lines comes from when you are closer to the plane’s edge rather that the plane itself).

Initially I used car like steering for the fish, and that looked good except for when it made sense to go over the top rather than around. So I implemented car like steering both horizontally and vertically to get submarine steering.

I’m using a simple waypoint pathing and no navmesh. And it is easy enough to calculate the required speed, lift and yaw. However, I needed to convert this into a 3d velocity vector for RVO, make the RVO changes and go back into speed, lift and yaw. Going back into speed, lift and yaw was my biggest challenge - I ended up using a numerical solver (that I dreamed up) and that worked fine (it would generally converge in 3-5 cycles).

The fish don’t group because they are individually going between each ball.

The fish spine arcs very much the same way described in the GDC presentation of The Flood in the Flame (thanks Gwen Frey).

I also created the fish and it has just 3 animations (idle, move and fast move).

Here is a video.