I figured them how to rotate camera matrix to horizon frame when view on planet surface. I studied rotation matrices on LearnOpenGL and Wikipedia website. I created code for horizon reference frame.
R = zRotate(lat) * yRotate(lng);
I wrote my own function calls from one of websites.
// rotation matrices for right-handed rule
template <typename T>
inline glm::dmat3 xRotate(T radians)
{
double sang = sin(radians), cang = cos(radians);
return glm::dmat3(
{ 1.0, 0.0, 0.0 },
{ 0.0, cang, -sang },
{ 0.0, sang, cang }
);
}
template <typename T>
inline glm::dmat3 yRotate(T radians)
{
double sang = sin(radians), cang = cos(radians);
return glm::dmat3(
{ cang, 0.0, sang },
{ 0.0, 1.0, 0.0 },
{-sang, 0.0, cang }
);
}
template <typename T>
inline glm::dmat3 zRotate(T radians)
{
double sang = sin(radians), cang = cos(radians);
return glm::dmat3(
{ cang, -sang, 0.0 },
{ sang, cang, 0.0 },
{ 0.0 , 0.0, 1.0 }
);
}
It worked but view is tilted 90 degrees counterclockwise. Surface is on left-side screen. I tried different coordinates like (0,0), (40,0), (40,40) etc., and it resulted the same but different surface. It looks good but view always was tilted 90 degrees counterclockwise. Does anyone know formula to rotate camera matrix to horizon level from north pole instead of equator? My code rotates camera view origin from (0, 0) equator on UTC line.
Also, I tried to rotate camera around surface, but it did not follow horizon frame but still follow global frame regardless of any rotation matrix.
double cphi = cos(go.phi), sphi = -sin(go.phi);
double ctheta = cos(go.theta), stheta = sin(go.theta);
rrot = { cphi, sphi*stheta, -sphi*ctheta,
0.0, ctheta, stheta,
sphi, -cphi*stheta, cphi*ctheta };
grot = R * rrot;
It did not work. I tried to rotate camera around surface but it still follows global frame instead of horizon frame (or reference frame). Does anyone know any code to rotate camera matrix to reference frame (or horizon frame)?