- /// Return a quaternion rotation from the earth centered to the
- /// OpenGL/viewer horizontal local frame from given longitude and latitude.
- /// This frame matches the usual OpenGL axis directions. That is the target
- /// frame has an x-axis pointing eastwards, y-axis pointing up and y z-axis
- /// pointing south.
- static SGQuat viewHLRad(T lon, T lat)
- {
- // That bails down to a 3-2-1 euler sequence lon+pi/2, 0, -lat-pi
- // what is here is again the hand optimized version ...
- SGQuat q;
- T xd2 = -T(0.5)*lat - T(0.5)*SGMisc<T>::pi();
- T zd2 = T(0.5)*lon + T(0.25)*SGMisc<T>::pi();
- T Szd2 = sin(zd2);
- T Sxd2 = sin(xd2);
- T Czd2 = cos(zd2);
- T Cxd2 = cos(xd2);
- q.w() = Cxd2*Czd2;
- q.x() = Sxd2*Czd2;
- q.y() = Sxd2*Szd2;
- q.z() = Cxd2*Szd2;
- return q;
- }
- /// Like the above provided for convenience
- static SGQuat viewHLDeg(T lon, T lat)
- { return viewHLRad(SGMisc<T>::deg2rad(lon), SGMisc<T>::deg2rad(lat)); }
- /// Like the above provided for convenience
- static SGQuat viewHL(const SGGeod& geod)
- { return viewHLRad(geod.getLongitudeRad(), geod.getLatitudeRad()); }
-
- /// Convert a quaternion rotation from the simulation frame
- /// to the view (OpenGL) frame. That is it just swaps the axis part of
- /// this current quaternion.
- /// That proves useful when you want to use the euler 3-2-1 sequence
- /// for the usual heading/pitch/roll sequence within the context of
- /// OpenGL/viewer frames.
- static SGQuat simToView(const SGQuat& q)
- { return SGQuat(q.y(), -q.z(), -q.x(), q.w()); }