API Question Custom Displays (Please help)

Here's a screenshot of my most recent build just to give everyone an idea of what I'm trying to do...



I finally have the propellant tanks reading normally and am now working on the "Stack Parameters Column" along the right side of the display. CG Offset, Engine Gimbal, and Vessel Mass are all functional.

What's holding me up now is the Payload Mass and by extention dV available. (one being a function of the other). Apperently there's no function in the standard OAPI for getting the mass of a combined superstructure (yet there's a function for CG what gives?).

I found the following in the SDK sample of the Burn Time Calulator MFD but could use some help understanding what is happening in it and adapting it to my purposes.

Code:
double BurnTimeMFD::GetStackMass(VESSEL* vessel) {
  //We don't have to worry about attachments. They either
  //are compensated for in the main vessel code, or arent,
  //in which case they have no mass. So, it's only docked
  //vessels which we care about

  //So, what we do is:
//Put the current vessel in the vessel-to-check list
  double totalMass=0;
  VESSEL* vesselsToCheck[100];
  int vesselsStored=0;
  vesselsToCheck[vesselsStored]=vessel;
  vesselsStored++;
//For each vessel in the vessel-to-check list
  for(int vesselsChecked=0;vesselsChecked<vesselsStored && vesselsChecked<100;vesselsChecked++) {
//  Accumulate this vessel's mass
    totalMass+=vesselsToCheck[vesselsChecked]->GetMass();
//  For each docking port
    UINT nDockingPorts=vesselsToCheck[vesselsChecked]->DockCount();
    for(UINT i_dock=0;i_dock<nDockingPorts;i_dock++) {
//    Get the docked vessel, if any,
      DOCKHANDLE hDock=vesselsToCheck[vesselsChecked]->GetDockHandle(i_dock);
      OBJHANDLE hVessel=vesselsToCheck[vesselsChecked]->GetDockStatus(hDock);
      VESSEL* pVessel=NULL;
      if(hVessel) pVessel=oapiGetVesselInterface(hVessel);
//    If it is not already in the vessel-to-check list
      bool hasVesselAlready=(pVessel==NULL);
      for(int i_vessel=0;i_vessel<vesselsStored;i_vessel++) if (vesselsToCheck[i_vessel]==pVessel) hasVesselAlready=true;
      if(!hasVesselAlready) {
//      Add it to the end of the list
        vesselsToCheck[vesselsStored]=pVessel;
        vesselsStored++;
//    end if
      }
//  end for
    }
//end for
  }
  return totalMass;
}

I tried simply copy/pasting it into my source code along with the declaration, but the value it returned was always null.
 
DV and stackmass issue has been adressed.

Even though the the effects have yet to be modeled, the Temp, Pressure, and Radioactivity gauges all work.

I'm posting everything I've done with the HUD's code so far as a courtesy to others...

Code:
//Render HUD
bool RNS::clbkDrawHUD (int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad *skp)
{
	//set center of screen as a reference point
	int roxl = ((hps->W)/2);
	int royl = ((hps->H)/2);

	// draw the default HUD
	VESSEL3::clbkDrawHUD (mode, hps, skp);
	oapiSetDefNavDisplay(1);
	oapiSetDefRCSDisplay(1);

	// define columns and rows for displaying text
	static int column[] = {(hps->W)/-3, (hps->W)/-6, 0, (hps->W)/6, (hps->W)/3};
	static int row[] = {-240,-224,-208,-192,-176,-160,-144,-128,-112,-96,-80,-64,-48,-32,-16, 0, 16, 32, 48, 64, 80, 96, 112, 128};

	// define parameters for text output
	#define HUDTextOut_CLR(skp, x, y, colour, text, ...)	{\
		DWORD old_clr = skp->SetTextColor(colour); \
		char buf[1024]; \
		sprintf_s(buf, 1024, text, __VA_ARGS__); \
		skp->Text (x+roxl, y+royl,buf, (int)strlen(buf));\
		skp->SetTextColor(old_clr);\
		}

	//double Main_Remaining, RCS_Remaining;
	//Main_Remaining = RNS::GetPropellantMass(ph_main); //Return amount of propellant currently in main tanks
	//RCS_Remaining = RNS::GetPropellantMass(ph_RCS); //Return amount of propellant currently in RCS tanks

	double Main_Remaining, RCS_Remaining, XePoisoning;
	Main_Remaining = GetFuelMass(); // Return amount of propellant currently in main tanks as fraction of tank capacity
	RCS_Remaining = GetTotalPropellantMass()-GetFuelMass(); //Return amount of propellant currently in RCS tanks as fraction of tank capacity
	XePoisoning = 0; // (not yet implimented)
	
	// Right Display Column
	HUDTextOut_CLR(skp, column[ 0], row[ 0], WHITE, "Propellant Remaining.");
	HUDTextOut_CLR(skp, column[ 0], row[ 1], GREEN, "Main:       %10.1f %%", Main_Remaining/RNS_MAINTANK*100); // Display main engine propellant remaining. [100% = full tank]
	HUDTextOut_CLR(skp, column[ 0], row[ 2], GREEN, "RCS:        %10.1f %%", RCS_Remaining/RNS_RCSTANK*100); // Display RCS propellant remaining. [100% = full tank]
	
	HUDTextOut_CLR(skp, column[ 0], row[ 4], WHITE, "NERVA Status:"); // Current operating mode, Standby, Warm-up, Nominal, Meltdown etc...   
	HUDTextOut_CLR(skp, column[ 0], row[ 5], GREEN, "Temp.      %10.1f %%", GetThrusterGroupLevel(THGROUP_MAIN)*100); // Reactor Temp (not yet implimented)
	HUDTextOut_CLR(skp, column[ 0], row[ 6], GREEN, "Pres.      %10.1f %%", 1*100); // Reactor Pressure (not yet implimented)
	HUDTextOut_CLR(skp, column[ 0], row[ 7], GREEN, "Prop. Flow %10.1f kg/s", GetFuelRate()); // Propellant flow [kg/s]
	HUDTextOut_CLR(skp, column[ 0], row[ 8], GREEN, "Exhst Vel. %10.1f km/s", GetThrusterIsp(th_main)/1000); // Exhaust Velocity [km/s]
	HUDTextOut_CLR(skp, column[ 0], row[ 9], GREEN, "Thrust.    %10.1f kn", GetThrusterLevel(th_main)*GetThrusterMax(th_main)/1000); // Thrust [kn]	
	HUDTextOut_CLR(skp, column[ 0], row[10], GREEN, "Reactivity %10.1f %%", XePoisoning*100); // Poisoning Level of radioactive isotopes (Xe135) in reactor [%] (not yet implimented)
	HUDTextOut_CLR(skp, column[ 0], row[11], WHITE, "Reactor Life span:"); // amount of time at max temp. before refurbishment is required
			int hrs = (int)floor(NTR_Life_s/3600.0);
			int mins = (int)floor((NTR_Life_s-3600.0*hrs)/60.0);
			int seconds = (int)(NTR_Life_s-3600.0*hrs-60.0*mins);
			HUDTextOut_CLR(skp, column[ 0], row[12], GREEN, "%d hrs. %d min. %d sec.", hrs, mins, seconds);

	// Center Display Column
	HUDTextOut_CLR(skp, column[ 1], row[19], GREEN, "   Commanded dV."); //(not yet implimented)
	HUDTextOut_CLR(skp, column[ 1], row[20], GREEN, "   Estimated Length of Burn"); //(not yet implimented)

	HUDTextOut_CLR(skp, column[ 1], row[22], WHITE, "   press [alt-m] to enter desired dV"); 
	HUDTextOut_CLR(skp, column[ 1], row[23], WHITE, "   press [spacebar] to initiate burn");

	double mass, totalmass;
	mass = GetMass();
	totalmass = GetStackMass(oapiGetFocusInterface());

	// Left Display Column
	HUDTextOut_CLR(skp, column[ 3], row[ 0], WHITE, "Stack Parameters.");
	HUDTextOut_CLR(skp, column[ 3], row[ 1], GREEN, "Vessel Mass:  %10.2f mt", mass/1000); // Mass of stage in metric tonnes
	HUDTextOut_CLR(skp, column[ 3], row[ 2], GREEN, "Payload Mass: %10.2f mt", (totalmass-mass)/1000); // Mass of payload in metric tonnes 
	HUDTextOut_CLR(skp, column[ 3], row[ 3], GREEN, "Total Mass:   %10.2f mt", totalmass/1000); // Total mass of stage in metric tonnes
	
	double Dv = GetThrusterIsp(th_main)*log((Main_Remaining/(totalmass-Main_Remaining))+1); // Tsiolkovsky's rocket equation

	HUDTextOut_CLR(skp, column[ 3], row[ 5], WHITE, "Estimated Dv available");
	HUDTextOut_CLR(skp, column[ 3], row[ 6], GREEN, "%0.1f Km/s", Dv/1000);

	HUDTextOut_CLR(skp, column[ 3], row[ 8], WHITE, "CG Offset:");
	HUDTextOut_CLR(skp, column[ 3], row[ 9], GREEN, "%0.2f deg X, %0.2f deg Y", RAD*asin(CG_Vector.x), RAD*asin(CG_Vector.y)); // CG's horizontal and vertical angle of offset
	
	HUDTextOut_CLR(skp, column[ 3], row[11], WHITE, "Engine Gimbal:");
	HUDTextOut_CLR(skp, column[ 3], row[12], GREEN, "%0.2f deg X, %0.2f deg Y", RAD*asin(CG_Vector.x), RAD*asin(CG_Vector.y)); // Main Engine Gimbal Setting

return true;
}

It's free to use
 
Back
Top