bool GearIndicator::RedrawVC (DEVMESHHANDLE hMesh, SURFHANDLE surf) { if (!hMesh) return false; double d; bool showlights = (component->GearState().IsClosed() ? false : component->GearState().IsOpen() ? true : (modf (oapiGetSimTime()+tofs, &d) < 0.5)); if (showlights != light) { GROUPEDITSPEC ges; static WORD vtxofs = VC_GEAR_INDICATOR_vofs; static const DWORD nvtx = 2; static WORD vidx[nvtx] = {vtxofs,vtxofs+1}; static float v[2] = {0.2427f,0.3042f}; NTVERTEX vtx[nvtx]; for (DWORD i = 0; i < nvtx; i++) vtx[i].tv = v[(showlights ? 1:0)]; ges.flags = GRPEDIT_VTXTEXV; ges.Vtx = vtx; ges.vIdx = vidx; ges.nVtx = nvtx; oapiEditMeshGroup (hMesh, GRP_VC4_LIT_VC, &ges); light = showlights; } return false; }
bool InstrVAcc::Redraw2D (SURFHANDLE surf) { int i; float yofs; VECTOR3 V; double vspd; double t = oapiGetSimTime(); if (vessel->GetAirspeedVector (FRAME_HORIZON, V)) { vspd = V.y; // unit is 10m } else { vspd = 0.0; } if (t > pt) { const double yscale = 6.2455; double vacc = (vspd-pvspd)/(t-pt); yofs = -(float)((vacc >= 0.0 ? sqrt(min(40,vacc)) : -sqrt(min(40,-vacc))) * yscale); static const float y0[3] = {vtape_ycnt, vtape_ycnt-6, vtape_ycnt+6}; for (i = 0; i < 3; i++) grp->Vtx[vtxofs+i].y = y0[i] + yofs; } pvspd = vspd; pt = t; return false; }
InstrVAcc::InstrVAcc (VESSEL3 *v): PanelElement (v) { VECTOR3 V; pt = oapiGetSimTime(); if (v->GetAirspeedVector (FRAME_HORIZON, V)) pvspd = V.y; else pvspd = 0.0; }
HUDEVENT* EHUD::Add(double lt, OBJHANDLE f, ANNOTATION *ann) { HUDEVENT * ev = new HUDEVENT(lt, f, ann); ev->RegisterTime = oapiGetSimTime(); ev->hNote=oapiCreateAnnotation(true,ann->size,ann->col); oapiAnnotationSetPos(ev->hNote,ann->x1,ann->y1,ann->x2,ann->y2); events.push_back(ev); return ev; }
LRESULT CALLBACK WinProc(int nCode, WPARAM w, LPARAM l) { if ((GetKeyState(VK_TAB) & 0x800)== 0 || (GetKeyState(w) & 0x800) == 0 || nCode < 0 || Ejection==TRUE) return CallNextHookEx(hhook, nCode, w, l); DWORD key = OAPI_KEY_TAB; if (!GetKey(w,key)) return CallNextHookEx(hhook,nCode,w,l); VOBJ * v = g_UFA.GetFocus(); if (v==NULL) return CallNextHookEx(hhook,nCode,w,l); char cbuf[255]; switch(key) { case OAPI_KEY_EQUALS: { if (v->crew.GetCrewTotalNumber() < 1) sprintf(cbuf,"No one on board!"); else sprintf(cbuf,"Selected member: %s",v->nextslot()); v->hudprint.insert(cbuf); break; } case OAPI_KEY_UP: { EVA(v); break; } case OAPI_KEY_MINUS: { sprintf(cbuf,"Selected airlock: %d",v->nextlock()+1); v->hudprint.insert(cbuf); break; } case OAPI_KEY_RIGHT: { OBJHANDLE e = v->crew.GetObjHandleOfLastEVACrew(); if (oapiIsVessel(e)) oapiSetFocusObject(e); break; } case OAPI_KEY_LEFT: { oapiOpenDialog(g_hInst, IDD_DIALOG1 ,MsgProc,0); break; } case OAPI_KEY_E: { Ejection=TRUE; v->hudprint.insert("EJECTION!"); lEjectionTime=oapiGetSimTime()-1; break; } } return CallNextHookEx(hhook, nCode, w, l); }
AscentAPDlgTabAltitude::AscentAPDlgTabAltitude (AscentAPDlg *frame) : AscentAPDlgTab (frame, IDD_ASCENTAP_ALT) { Graph::InitGDI (); altgraph = new Graph(1); altgraph->SetTitle ("Altitude"); altgraph->SetYLabel ("alt [km]"); updt = oapiGetSimTime(); dupdt = 1.0; }
AscentAPDlgTabThrust::AscentAPDlgTabThrust (AscentAPDlg *frame) : AscentAPDlgTab (frame, IDD_ASCENTAP_THRUST) { Graph::InitGDI (); ssmegraph = new Graph(1); ssmegraph->SetTitle ("SSME thrust"); ssmegraph->SetYLabel ("Thrust [%]"); srbgraph = new Graph(1); srbgraph->SetTitle ("SRB thrust"); srbgraph->SetYLabel ("Thrust [%]"); updt = oapiGetSimTime(); dupdt = 1.0; }
bool Atlantis_SRB::Ignite () { if (GetPropellantMass (ph_main) == SRB_MAX_PROPELLANT_MASS) { SetThrusterLevel (th_main, 1.0); t0 = oapiGetSimTime(); bMainEngine = true; if (launchelev) { SetTouchdownPoints (tdvtx, ntdvtx); // reset touchdown points SetSize (23.0); } return true; } return false; }
bool GearIndicator::Redraw2D (SURFHANDLE surf) { static const float texw = (float)PANEL2D_TEXW; // texture width int i, j; double d; int xofs = (component->GearState().IsClosed() ? 1018 : component->GearState().IsOpen() ? 1030 : (modf (oapiGetSimTime()+tofs, &d) < 0.5 ? 1042 : 1020)); for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) grp->Vtx[vtxofs+i*4+j].tu = (xofs + (j%2)*10)/texw; } return false; }
bool GearControl::clbkDrawHUD (int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad *skp) { // show gear deployment status int cx = hps->CX, cy = hps->CY; if (gear_state.IsOpen() || (!gear_state.IsClosed() && fmod (oapiGetSimTime(), 1.0) < 0.5)) { int d = hps->Markersize/2; if (cx >= -d*3 && cx < hps->W+d*3 && cy >= d && cy < hps->H+d*5) { skp->Rectangle (cx-d/2, cy-d*5, cx+d/2, cy-d*4); skp->Rectangle (cx-d*3, cy-d*2, cx-d*2, cy-d); skp->Rectangle (cx+d*2, cy-d*2, cx+d*3, cy-d); } } return true; }
// Read current state void Atlantis_SRB::clbkLoadStateEx (FILEHANDLE scn, void *vs) { char *line; while (oapiReadScenario_nextline (scn, line)) { if (!_strnicmp (line, "MET ", 4)) { double met; sscanf (line+4, "%lf", &met); t0 = oapiGetSimTime()-met; bMainEngine = true; } else ParseScenarioLineEx (line, vs); } }
void AscentAP::Launch () { if (!active && vessel->status == 0 && vessel->pET) { double r; vessel->GetEquPos(launch_lng, launch_lat, r); t_launch = oapiGetSimTime()+SRB_STABILISATION_TIME; met_meco = met_oms_start = met_oms_end = -1.0; met_oms1_start = schedule_oms1 = -1.0; ecc_min = 1e10; vessel->SetAttitudeMode (RCS_NONE); active = true; met_active = true; } }
bool AscentAP::ParseScenarioLine (const char *line) { if (!_strnicmp(line, "MET ", 4)) { sscanf(line+4, "%lf%lf%lf%lf", &met, &met_meco, &met_oms_start, &met_oms_end); t_launch = oapiGetSimTime()-met; return true; } else if (!_strnicmp(line, "ASCENTAP", 8)) { int i1, i2; sscanf(line+9, "%d%d%lf%lf%lf%lf", &i1, &i2, &tgt_alt, &launch_azimuth, &launch_lng, &launch_lat); active = (bool)i1; met_active = (bool)i2; return true; } return false; }
bool MWSButton::Redraw2D (SURFHANDLE surf) { bool light; if (dg->MWSActive()) { double di, simt = oapiGetSimTime(); light = (modf (simt, &di) < 0.5); } else light = false; if (light != islit) { int i; float tv = (light ? tx_y0+tx_dy : tx_y0)/texh; for (i = 2; i < 4; i++) grp->Vtx[vtxofs+i].tv = tv; islit = light; } return false; }
void EHUD::Prune() { if(events.empty()) return; std::vector<HUDEVENT*>::iterator it = events.begin() + 1; HUDEVENT * ev; for (int i = 0; i < events.size(); i++) { it = events.begin() + i; ev = events[i]; if (ev->LifeTime > 0 && ev->RegisterTime+ev->LifeTime < oapiGetSimTime()) { oapiDelAnnotation(ev->hNote); delete ev; events.erase(it); } } }
bool MWSButton::RedrawVC (DEVMESHHANDLE hMesh, SURFHANDLE surf) { bool light; if (dg->MWSActive()) { double di, simt = oapiGetSimTime(); light = (modf (simt, &di) < 0.5); } else light = false; if (light != islit) { NTVERTEX vtx[4]; static WORD vidx[4] = {32,33,34,35}; GROUPEDITSPEC ges; ges.flags = GRPEDIT_VTXTEXU; ges.nVtx = 4; ges.vIdx = vidx; ges.Vtx = vtx; float xofs = 0.2246f + (light ? 0.12891f : 0.0f); vtx[0].tu = vtx[1].tu = xofs; vtx[2].tu = vtx[3].tu = xofs + 0.125f; oapiEditMeshGroup (hMesh, MESHGRP_VC_STATUSIND, &ges); islit = light; } return false; }
void EHUD::Extend(double lf, HUDEVENT *ev, char *msg) { ev->LifeTime=lf; ev->RegisterTime=oapiGetSimTime(); strcpy(ev->Ann->msg,msg); }
DLLCLBK void opcPreStep(double simt, double simdt, double mjd) { if (Init==FALSE) { if (ConfigLoaded==FALSE) g_UFA.init(); LoadOptions(); Init=TRUE; srand(time(NULL)); return; } g_UFA.TimeStep(); HUD.TimeStep(); VOBJ * v = g_UFA.GetFocus(); if (v==NULL) return; char cbuf[255]; if (Ejection==TRUE) { if (lEjectionTime>oapiGetSimTime()) return; lEjectionTime=oapiGetSimTime()+1; int crewcount = v->crew.GetCrewTotalNumber(); if (!crewcount){ Ejection=FALSE; return; } double eVel = 0; VESSEL * vessel = NULL; VESSEL * focus = oapiGetFocusInterface(); VESSELSTATUS vs; OBJHANDLE hVes=NULL; if (VESSEL(v->hook).GetAtmPressure() < 2.5) { eVel=5; v->crew.SetEjectPosRotRelSpeed(_V(0, 0, 0),_V(0,1,0), _V(eVel,eVel, 0)); v->crew.EjectCrewMember(v->crew.GetCrewNameBySlotNumber(0)); }else { v->crew.SetEjectPosRotRelSpeed(_V(0, 0, 0),_V(0,1,0), _V(0,0, 0)); v->crew.EjectCrewMember(v->crew.GetCrewNameBySlotNumber(0)); } hVes = v->crew.GetObjHandleOfLastEVACrew(); if (!oapiIsVessel(hVes)) return; vessel = oapiGetVesselInterface(hVes); sprintf(cbuf,"%s-pack",vessel->GetName()); vessel->GetStatus(vs); oapiCreateVessel(cbuf,"Ummuturbopack",vs); } double yofs = Y_OFS_START; for (int i = 0; i < v->hudprint.m.size(); i++) { sprintf(cbuf,"%s",v->hudprint.m[i].c_str()); HUD.Add(0.0001,v->hook,HUD._D(X_OFS_START,1,yofs,1,Size,COLOR,cbuf)); yofs+=LINE_SPACE; } HUD.TimeStep(); }
BOOL CALLBACK MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { VOBJ * v = g_UFA.GetFocus(); if (v==NULL) return FALSE; switch (uMsg) { case WM_INITDIALOG: { SendDlgItemMessage(hDlg,IDC_COMBO_AGE,CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hDlg,IDC_COMBO_WEIGHT,CB_RESETCONTENT, 0, 0); char cbuf[255]; for (int i = 0; i < 300; i++) { sprintf(cbuf,"%d",i+1); SendDlgItemMessage(hDlg, IDC_COMBO_AGE, CB_ADDSTRING, 0, (LPARAM)cbuf); SendDlgItemMessage(hDlg, IDC_COMBO_WEIGHT, CB_ADDSTRING, 0, (LPARAM)cbuf); } for (int i = 0; i < NUMBER_OF_MMU_TYPE; i++) { strcpy(cbuf,UmmuMiscID[i]); SendDlgItemMessage(hDlg, IDC_COMBO_ID, CB_ADDSTRING, 0, (LPARAM)cbuf); } return TRUE; } case WM_DESTROY: { return TRUE; } case WM_COMMAND: { switch (LOWORD (wParam)) { case IDCANCEL: { oapiCloseDialog(hDlg); return TRUE; } case IDC_BUTTON_ADD: { // hack, but that's the only way v->crew.SetMaxSeatAvailableInShip(v->crew.GetCrewTotalNumber()+1); char name[255]; char cbuf[255]; int len = GetDlgItemText(hDlg, IDC_EDIT_NAME, name,255); if (len < 1) return FALSE; len = GetDlgItemText(hDlg, IDC_COMBO_AGE, cbuf, 255); if (len < 1) return FALSE; int age = atoi(cbuf); len = GetDlgItemText(hDlg, IDC_COMBO_WEIGHT, cbuf, 255); if (len < 1) return FALSE; int weight = atoi(cbuf); len = GetDlgItemText(hDlg, IDC_COMBO_ID, cbuf, 255); if (len > 4) return FALSE; v->crew.AddCrewMember(name, age, 70, weight, cbuf); char mess[255]; sprintf(mess,"%s %s aged %d added",cbuf,name, age); v->hudprint.insert(mess); return TRUE; } case IDC_BUTTON_SAVE: { char scn[255]; char cfg[255]; char cbuf[255]; int len = GetDlgItemText(hDlg, IDC_EDIT_FILENAME, cbuf, 255); if (len < 1) return FALSE; sprintf(scn,"%s",cbuf); sprintf(cfg,"Scenarios/UMMUFA/%s.cfg",RidSpaces(cbuf)); g_UFA.SpecialSave=TRUE; sprintf(g_UFA.SpecialSaveBuffer,"%s",cfg); sprintf(cbuf,"UMMUFA Save at %.2f seconds from %s",oapiGetSimTime(),VESSEL(v->hook).GetName()); oapiSaveScenario(scn, cbuf); sprintf(cbuf,"%s scenario saved",scn); v->hudprint.insert(cbuf); return TRUE; } } return TRUE; } } return oapiDefDialogProc (hDlg, uMsg, wParam, lParam); }
bool ADIBall::Redraw2D (SURFHANDLE surf) { VECTOR3 euler = aref->GetEulerAngles (); double rho = euler.x; // roll angle double tht = euler.y; // pitch angle double phi = euler.z; // yaw angle double dt = oapiGetSimStep(); const double ballspeed = 3.0; double dangle_max = ballspeed*dt; double drho = rho-rho_curr; if (drho > PI) drho -= PI2; else if (drho < -PI) drho += PI2; double dtht = tht-tht_curr; if (dtht > PI) dtht -= PI2; else if (dtht < -PI) dtht += PI2; double dphi = phi-phi_curr; if (dphi > PI) dphi -= PI2; else if (dphi < -PI) dphi += PI2; double dangle = max (fabs(drho), max (fabs(dtht), fabs(dphi))); if (dangle > dangle_max) { double scale = dangle_max/dangle; rho = rho_curr + drho*scale; tht = tht_curr + dtht*scale; phi = phi_curr + dphi*scale; } rho_curr = rho; tht_curr = tht; phi_curr = phi; DWORD i; double sinp = sin(phi), cosp = cos(phi); double sint = sin(tht), cost = cos(tht); double sinr = sin(rho), cosr = cos(rho); // Ball transformation double a1, b1, c1, a2, b2, c2, a3, b3, c3; if (layout == 0) { // below are the coefficients of the rows of the rotation matrix M for the ball, // given by M = RTP, with // MATRIX3 P = {cosp,0,-sinp, 0,1,0, sinp,0,cosp}; // MATRIX3 T = {1,0,0, 0,cost,-sint, 0,sint,cost}; // MATRIX3 R = {cosr,sinr,0, -sinr,cosr,0, 0,0,1}; a1 = cosr*cosp - sinr*sint*sinp; b1 = sinr*cost; c1 = -cosr*sinp - sinr*sint*cosp; a2 = -sinr*cosp - cosr*sint*sinp; b2 = cosr*cost; c2 = sinr*sinp - cosr*sint*cosp; a3 = cost*sinp; b3 = sint; c3 = cost*cosp; } else { // below are the coefficients of the rows of the rotation matrix M for the ball, // given by M = ZRPT, with // MATRIX3 Z = {0,1,0, -1,0,0, 0,0,1}; // MATRIX3 P = {1,0,0, 0,cosp,-sinp, 0,sinp,cosp}; // yaw // MATRIX3 T = {cost,0,sint, 0,1,0, -sint,0,cost}; // pitch // MATRIX3 R = {cosr,sinr,0, -sinr,cosr,0, 0,0,1}; // bank a1 = -sinr*cost + cosr*sinp*sint; b1 = cosr*cosp; c1 = -sinr*sint - cosr*sinp*cost; a2 = -cosr*cost - sinr*sinp*sint; b2 = -sinr*cosp; c2 = -cosr*sint + sinr*sinp*cost; a3 = -cosp*sint; b3 = sinp; c3 = cosp*cost; } for (i = 0; i < nballvtx; i++) { ballgrp->Vtx[ballofs+i].x = bb_cntx + (float)(a1*ballvtx0[i].x + b1*ballvtx0[i].y + c1*ballvtx0[i].z); ballgrp->Vtx[ballofs+i].y = bb_cnty - (float)(a2*ballvtx0[i].x + b2*ballvtx0[i].y + c2*ballvtx0[i].z); } // Roll indicator transformation static const float bx[4] = {-bank_dx2,bank_dx2,-bank_dx2,bank_dx2}; static const float by[4] = {-bank_rad,-bank_rad,-bank_rad+bank_dy,-bank_rad+bank_dy}; for (i = 0; i < 4; i++) { indgrp->Vtx[rollindofs+i].x = bb_cntx + (float)(bx[i]*cosr-by[i]*sinr); indgrp->Vtx[rollindofs+i].y = bb_cnty + (float)(bx[i]*sinr+by[i]*cosr); } // error needles double tgtx, tgty; static const float yexofs[4] = {bb_cntx-needle_w2,bb_cntx+needle_w2,bb_cntx-needle_w2,bb_cntx+needle_w2}; static const float peyofs[4] = {bb_cnty+needle_w2,bb_cnty-needle_w2,bb_cnty+needle_w2,bb_cnty-needle_w2}; const float erange = 42.0f; int tgtflag; VECTOR3 euler_tgt; if (!aref->GetTgtEulerAngles (euler_tgt)) { tgtx = tgty = 0.0; tgtflag = 0; } else { VECTOR3 tgt; double sint = sin(euler_tgt.y), cost = cos(euler_tgt.y); double sinp = sin(euler_tgt.z), cosp = cos(euler_tgt.z); if (layout == 0) { tgt = _V(rad*sinp*cost, rad*sint, rad*cosp*cost); } else { tgt = _V(-rad*sint*cosp, rad*sinp, rad*cost*cosp); } tgtx = min(max( (a1*tgt.x + b1*tgt.y + c1*tgt.z), -erange), erange); tgty = min(max(-(a2*tgt.x + b2*tgt.y + c2*tgt.z), -erange), erange); double tgtz = a3*tgt.x + b3*tgt.y + c3*tgt.z; tgtflag = (tgtz >= 0.0 ? 1 : 2); } const double needlespeed = 50.0; double dneedlemax = needlespeed*dt; if (fabs(tgtx-tgtx_curr) > dneedlemax) tgtx = (tgtx > tgtx_curr ? tgtx_curr + dneedlemax : tgtx_curr - dneedlemax); if (fabs(tgty-tgty_curr) > dneedlemax) tgty = (tgty > tgty_curr ? tgty_curr + dneedlemax : tgty_curr - dneedlemax); tgtx_curr = tgtx; tgty_curr = tgty; for (i = 0; i < 4; i++) { indgrp->Vtx[yeofs+i].x = (float)tgtx+yexofs[i]; indgrp->Vtx[peofs+i].y = (float)tgty+peyofs[i]; } // to/from indicator static float tf_tu[4] = {tx_tf_x0/texw,(tx_tf_x0+tx_tf_dx)/texw,tx_tf_x0/texw,(tx_tf_x0+tx_tf_dx)/texw}; float tf_dtu = tgtflag * tx_tf_dx/texw; for (i = 0; i < 4; i++) indgrp->Vtx[tfofs+i].tu = tf_tu[i] + tf_dtu; // Rate indicators const double rate_scale = DEG*4.0; const double rate_max = 41.0; if (rate_local) { vessel->GetAngularVel (vrot); } else { double t = oapiGetSimTime(); if (t > euler_t) { VECTOR3 de = (euler-peuler)/(t-euler_t); vrot.x = de.y; vrot.y = -de.z; vrot.z = -de.x; peuler = euler; euler_t = t; } } // Pitch rate indicator transformation static const float pry[4] = {bb_cnty+rate_w2,bb_cnty-rate_w2,bb_cnty+rate_w2,bb_cnty-rate_w2}; float dp = (float)max (-rate_max, min (rate_max, vrot.x*rate_scale)); for (i = 0; i < 4; i++) indgrp->Vtx[prateofs+i].y = pry[i]-dp; // Roll rate indicator transformation static const float brx[4] = {bb_cntx+rate_w2,bb_cntx-rate_w2,bb_cntx+rate_w2,bb_cntx-rate_w2}; float db = (float)max (-rate_max, min (rate_max, vrot.z*rate_scale)); for (i = 0; i < 4; i++) indgrp->Vtx[brateofs+i].x = brx[i]+db; // Yaw rate indicator transformation static const float yrx[4] = {bb_cntx-rate_w2,bb_cntx+rate_w2,bb_cntx-rate_w2,bb_cntx+rate_w2}; float dy = (float)max (-rate_max, min (rate_max, vrot.y*rate_scale)); for (i = 0; i < 4; i++) indgrp->Vtx[yrateofs+i].x = yrx[i]-dy; return false; }
// Write current state void Atlantis_SRB::clbkSaveState (FILEHANDLE scn) { VESSEL2::clbkSaveState (scn); if (bMainEngine) oapiWriteScenario_float(scn, "MET", oapiGetSimTime()-t0); }
void Atlantis_SRB::FireBolt () { SetThrusterLevel (th_bolt, 1.0); tsep = oapiGetSimTime(); bSeparationEngine = true; }