I finally decided to use the standard mesh layout for height maps instead of the diamond pattern you see in ROAM implementations and the normals now look fine. Before switching to this standard triangle layout I tried several other normal calculation methods, but still got those ugly cross hatches that you see in my previous posts.
Here's what the normals look like fixed:
And the wireframe version:
I still need to cache the vertex normals and tangents for the edges of each mesh to make the transition from large meshes to smaller resolution meshes seamless. Right now there are seams that I had fixed in my previous version that used the diamond pattern mesh.
After I fix that I plan on moving from a static image that is loaded from disk to a random image generated by the program so that I can test different planets.
After getting that working I'll need to fix some issues that come up when calculating normals that are on the edges of two (or three) faces. I will probably do some kind of vertex normal/tangent sharing similar to how I will share edge normals between separate quad tree nodes on the same face.
Here's a cute screenshot I took when debuggin the normals: