const MATRIX3 &AttitudeReference::GetFrameRotMatrix () const { // Returns rotation matrix for rotation from reference frame to global frame if (!valid_axes) { VECTOR3 axis1, axis2, axis3; switch (mode) { case 0: // inertial (ecliptic) axis3 = _V(1,0,0); axis2 = _V(0,1,0); break; case 1: { // inertial (equator) MATRIX3 R; oapiGetPlanetObliquityMatrix (v->GetGravityRef(), &R); //axis3 = _V(R.m13, R.m23, R.m33); axis3 = _V(R.m11, R.m21, R.m31); axis2 = _V(R.m12, R.m22, R.m32); } break; case 2: { // orbital velocity / orbital momentum vector OBJHANDLE hRef = v->GetGravityRef(); v->GetRelativeVel (hRef, axis3); axis3 = unit (axis3); VECTOR3 vv, vm; v->GetRelativePos (hRef, vv); // local vertical vm = crossp (axis3,vv); // direction of orbital momentum axis2 = unit (crossp (vm,axis3)); } break; case 3: { // local horizon / local north (surface) OBJHANDLE hRef = v->GetSurfaceRef(); v->GetRelativePos (hRef, axis2); axis2 = unit (axis2); MATRIX3 prot; oapiGetRotationMatrix (hRef, &prot); VECTOR3 paxis = {prot.m12, prot.m22, prot.m32}; // planet rotation axis in global frame VECTOR3 yaxis = unit (crossp (paxis,axis2)); // direction of yaw=+90 pole in global frame axis3 = crossp (axis2,yaxis); } break; case 4: { // synced to NAV source (type-specific) NAVDATA ndata; NAVHANDLE hNav = v->GetNavSource (navid); axis3 = _V(0,0,1); axis2 = _V(0,1,0); if (hNav) { oapiGetNavData (hNav, &ndata); switch (ndata.type) { case TRANSMITTER_IDS: { VECTOR3 pos, dir, rot; MATRIX3 R; VESSEL *vtgt = oapiGetVesselInterface (ndata.ids.hVessel); vtgt->GetRotationMatrix (R); vtgt->GetDockParams (ndata.ids.hDock, pos, dir, rot); axis3 = -mul(R,dir); axis2 = mul(R,rot); } break; case TRANSMITTER_VTOL: case TRANSMITTER_VOR: { OBJHANDLE hRef = v->GetSurfaceRef(); VECTOR3 spos, npos; v->GetRelativePos (hRef, axis2); v->GetGlobalPos (spos); axis2 = unit (axis2); oapiGetNavPos (hNav, &npos); npos -= spos; axis3 = unit(crossp(crossp(axis2,npos),axis2)); } break; } } } break; } axis1 = crossp(axis2,axis3); R = _M(axis1.x, axis2.x, axis3.x, axis1.y, axis2.y, axis3.y, axis1.z, axis2.z, axis3.z); valid_axes = true; valid_euler = false; } return R; }