No one answered mine. I realized to have to explain more specific…
I am using geocentric coordinate from equatorial coordinate (longitude and latitude) with altitude from (0, 0, 0). Z points to me (in right-handed rule). It is working perfect.
inline glm::dvec3 getGeocentric(double lat, double lng, double rad)
{
double slat = sin(lat), clat = cos(lat);
double slng = sin(lng), clng = cos(lng);
double xz = rad * clat;
return { xz*clng, rad*slat, xz*-slng };
}
I need horizon reference frame (rotation matrix) to make camera to point to horizon level where north pole is from equatorial coordinate (longitude and latitude). Then I can rotate camera direction around and move it to other location. I quoted that from DirectX code because DirectX uses left-handed rule. I need to convert to right-handed rule.
go.lng = lng;
go.lat = lat;
double clng = cos(lng), slng = -sin(lng);
double clat = cos(lat), slat = sin(lat);
go.R = { clng*slat, clng*clat, -slng,
-clat, slat, 0,
slng*slat, slng*clat, clng };
That did not work because it did not point to horizon level at zero heading as default. It looks like left-handed rule. I tried to negate longtitude for right-handed rule, but it did not work. It still did not point to horizon level. I need right-handed rule version of horizon frame. I ended up looking down to ground instead of horizon level. When I brought camera up, but it was not at level (tilted off 20-30 degrees).
// camera direction
go.phi = glm::radians(150); // 150 degrees heading
go.theta = pi/2.0; // point to horizon level
// Calculating local horizon frame camera coordinates
double cphi = cos(go.phi), sphi = -sin(go.phi);
double ctheta = cos(go.theta), stheta = sin(go.theta);
cam.rrot = { cphi, sphi*stheta, -sphi*ctheta,
0.0, ctheta, stheta,
sphi, -cphi*stheta, cphi*ctheta };
lrot = go.R * cam.rrot; // with horizon ref frame
grot = s0.R * lrot; // with rotating planet
Note: go = ground observer structure with equatorial coordinates (longitude and latitude), altitude, etc. It still did not work because it did not point to horizon level at 150 degrees heading. It still points to ground 20-30 degrees down and off course from 150 heading. But that is left-handed rule from DirectX code. I need right-handed rule.