Project Westcott RPE (Upgrade)

Made a test map to get an understanding of panel bitmaps versus the panel action area.

This is the 2048x1024 bitmap(in .jpg for space)
http://i89.photobucket.com/albums/k207/Notebook_04/Test_1_.jpg

This is a screenshot from Orbiter:
http://i89.photobucket.com/albums/k207/Notebook_04/11051610-09-16Westcott_P2.jpg

Changed the static DWORD panelH = 400; to = 800; for a full height panel, and removed the scrolling option from
SetPanelBackground (hPanel, &panel2dtex, 1, hPanelMesh, panelW, panelH, 0,
PANEL_ATTACH_BOTTOM );

I was expecting the screenshot to be from 0,0 to 1280,800. However it goes from 0,253 to 1280,1024. So a vertical offset of 253 and a panel height of 771 pixels not 800? Are the 29 pixels part of Orbiter's title bar?

All input appreciated.

N.
 
I was expecting the screenshot to be from 0,0 to 1280,800. However it goes from 0,253 to 1280,1024. So a vertical offset of 253 and a panel height of 771 pixels not 800? Are the 29 pixels part of Orbiter's title bar?

If you want it to start from the top of the texture instead to the bottom, change yours:
Code:
  static NTVERTEX VTX[4] = {
    {      0,      0,0,   0,0,0,                0.0f,[highlight]1.0f-fpanelH/ftexH[/highlight]},
    {      0,fpanelH,0,   0,0,0,                0.0f,[highlight]1.0f[/highlight]              },
    {fpanelW,fpanelH,0,   0,0,0,       fpanelW/ftexW,[highlight]1.0f[/highlight]              },
    {fpanelW,      0,0,   0,0,0,       fpanelW/ftexW,[highlight]1.0f-fpanelH/ftexH[/highlight]}
  };
  static WORD IDX[6] = {
    0,2,1,
    2,0,3
  };

- to this:
Code:
  static NTVERTEX VTX[4] = {
    {      0,      0,0,   0,0,0,                0.0f,[highlight]0.0f[/highlight]         },
    {      0,fpanelH,0,   0,0,0,                0.0f,[highlight]fpanelH/ftexH[/highlight]},
    {fpanelW,fpanelH,0,   0,0,0,       fpanelW/ftexW,[highlight]fpanelH/ftexH[/highlight]},
    {fpanelW,      0,0,   0,0,0,       fpanelW/ftexW,[highlight]0.0f[/highlight]         }
  };
  static WORD IDX[6] = {
    0,2,1,
    2,0,3
  };

The 771 pixels is most likely from the title bar in windowed mode maximized at 1280x800 screen. In full screen, 1280x800 mode it should be 800 pixels.
 
Got to this so far:
http://i89.photobucket.com/albums/k207/Notebook_04/11051811-43-38Westcott_P2.jpg

with this bitmap:
http://i89.photobucket.com/albums/k207/Notebook_04/WestcottP2_8_.jpg

Looking at this code at the moment:
const int btnw = 16; // button label area width
const int btnh = 16; // button label area height
int btn, x, len, i, w;
const char *label;
for (btn = 0; btn < 6; btn++) {
// blank buttons \note This function copies rectangular areas between two surfaces, or between two locations of the same surface.
//oapiBlt (surf, surf, xcnt-btnw/2, ytop+dy*btn, 1300, 0, 16, 16);
oapiBlt (surf, surf, xcnt-btnw/2, ytop+dy*btn, 1300,16, blank_btn_x+btnw, blank_btn_y+btnh);
// write labels
if (label = oapiMFDButtonLabel (MFD_LEFT, btn+lr*6)) {
len = strlen(label);
sprintf (oapiDebugString(), "my value is %s", label);
for (w = i = 0; i < len; i++)
w += MFD_font_width[label];
for (i = 0, x = xcnt-w/2; i < len; i++) {
w = MFD_font_width[label];
if (w) {
oapiBlt (surf, surf, x, ytop_dy*btn, MFD_font_xpos[label],
MFD_font_ypos, w, MFD_font_height);
x += w;
}
}
} else break;
}
return false;
}

I've put some of my own constants, and a DebugString in to see whats going on.

Happy with the first oapiBlt that puts the background back onto the buttons, just a query with the next one, that puts the three letter labels on the buttons.

Where does it get the font from?
I've copied the DeltaGlider font info into my code:
const int MFD_font_xpos[256] = { // MFD label font: character x-offsets
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...and so on
and:
const int MFD_font_width[256] = { // MFD label font: character widths
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...and so on
Haven't put any font into the bitmap(Test_1_.dds") yet, not sure where it should go pixel wise?

All input appreciated.

N.
 
Back to the 2dpanel blog from martins, after a work break.

Quick question.


In "Lesson 5: Adding an MFD", code section 6:

Code:
...
// blank buttons
    oapiBlt (surf, surf, xcnt-btnw/2, ytop+dy*btn,
      blank_btn_x, blank_btn_y, blank_btn_x+btnw, blank_btn_y+btnh);
...

Should "ytop+dy", (fourth parameter)be "ytop_dy"?

I was going to put this in martins blog comments part, but not sure of the answer.

N.
 
Had a review of my VisSim model of RZ-2 engine lox pressurisation system. Simplified it a bit, gravity fill for the run tank, and assuming the tanks don't go below ambient pressure, so no collapse!

If anyone sees any obvious problems please point them out, otherwise I'll get on with the hard bit, and stop drawing pictures...

http://i89.photobucket.com/albums/k207/Notebook_04/LoxPress_1_.jpg

N.
 
Plodding on wit the meshes:

http://i89.photobucket.com/albums/k207/Notebook_04/WestcottP2_Max2.jpg

http://i89.photobucket.com/albums/k207/Notebook_04/WestcottP2_Max3.jpg

http://i89.photobucket.com/albums/k207/Notebook_04/WestcottP2_Max1.jpg

As you can see from Max1 above, I haven't started on the Firing Bunker, but there's space for it.

Question time again!
I've asked before if I should split the mesh, and opinions are its simpler to keep it as one.
Can I deviate a bit, and keep the "static" bits, the ground mesh, tanks, pipework, ducting
as a seperate mesh, then load that lot from the .dll. The .dll will have the Firing Bunker, the engines, all the external animation?

All input appreciated.

N.
 
I've asked before if I should split the mesh, and opinions are its simpler to keep it as one.
Can I deviate a bit, and keep the "static" bits, the ground mesh, tanks, pipework, ducting
as a seperate mesh, then load that lot from the .dll. The .dll will have the Firing Bunker, the engines, all the external animation?

Yes, that makes sense. it also simplifies alignment of the .dll vessel, if you have some reference objects in the base.

But I would maybe leave the small ducting and pipes part of the vessel, but as separate mesh, that you only make visible of the camera distance is less than x meters. Otherwise the pure presence of the pipes in the display frustum slows the rendering.
 
Thanks Urwumpe.
Its starting to get a bit mesh heavy now, and on the machine I use to develop(Compaq Presario, about 6/7 years old) its getting a bit flaky. Still runs ok on a 2/3 year old PC box, so I'm guessing its polygons and things...

I'll have to split it , as I want the Firing Bunker extrenal/internal and engine gimbaling, water deluge, rocket exhausts as a different "project". At least thats the theory!

I'll use the 2d panel system, did some work on that! Was thinking of a MFD for each engine pack, varius pages for the subsytems, and a master MFD for running tests and results.
I would like to have a 1960's look to the panels and gauges, bit like this:
http://i89.photobucket.com/albums/k207/Notebook_04/Blue Streak/ControlRoom.jpg

(Like all those chart recorders, not sure about the clock though...)

thats probably beyond my graphics skill at the moment, one day perhaps!

N.


N.
 
Looking a bit closer at the engines geometry.

Using this:
http://i89.photobucket.com/albums/k207/Notebook_04/Blue Streak/File0044.jpg

After a bit of cut and paste and putting some dimensions in:
http://i89.photobucket.com/albums/k207/Notebook_04/Blue Streak/File0052.jpg

I've stuck the engines under the plan view of the propulsion bay, hopefully it'll be clear what I'm doing.

Its all about the engines coming into contact.

The propulsion bay is 8 feet in diameter, I've converted all dimensions into metric.
From the diagram, the engine nozzles are just touching the edges of the bay. They have a diameter of 1.101m, so subtracting 2 times this from 2.438m of the bay gives an engine nozzle spacing of 0.236m.

The maximum engine gimbal is 7 degrees, sine of this is 0.121869343, round up to .122.

The gimbal to nozzle distance is 2.45m, so multiplying by sine(7degrees) gives the distance the nozzle edge will move?

I get 0.299m rounded up.

This is more than the nozzle spacing?

I can't see any mechanical inhibits, so the gimbal control must take care of this, or have I missed something(there's a thought).

All input appreciated.

N.
 
Working on the Control_Bunker MFD's, using the MFDTemplate in the SDK/Samples, with help from here:
http://www.orbiter-forum.com/showthread.php?t=24897&highlight=Sketchpad

Got this far:
http://i89.photobucket.com/albums/k207/Notebook_04/LoxMFD_1.jpg

I can't get the Grey pen to draw in dashed style.


Edit:
After a bit of prodding, it only draws dashed on 1 pixel lines. Trying to draws pipes with diferent gases, so looks like rectangles and brushes!

Got the graphic done:
http://i89.photobucket.com/albums/k207/Notebook_04/Control_2.jpg

Just got to get it to work!

All input appreciated.

N.
 
Last edited:
Finished the first of the MFD screens, using the MFDTemplate sample:

http://i89.photobucket.com/albums/k207/Notebook_04/LoxMFD_2.jpg

Time to make a panel for the Control_Bunker.

Thought I was getting on ok, but...getting this error from the linker

Code:
Control_Bunker.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall Control_Bunker::clbkLoadPanel2D(int,void *,unsigned long,unsigned long)" (?clbkLoadPanel2D@Control_Bunker@@UAE_NHPAXKK@Z)
C:\Orbiter100830\Modules\Control_Bunker.dll : fatal error LNK1120: 1 unresolved externals


I had already passed this point, as you can see from previous posts, just wondering if this is down to a switch to 2010 C++ Express from the 2008 version?

This is the line that gives the error

Code:
bool clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH);

comment tha out and it links fine.

Starting from page one of Martin's "Developer masterclass: Creating 2-D panels the new way"
http://www.orbiter-forum.com/blog.php?b=574

I think I know eneough now to realise its a Linker error, and it can't find that function. Checked the Linker page in Properties and it has this for additional libraries
Code:
C:\Orbiter100830\Orbitersdk\lib;%(AdditionalLibraryDirectories)

All input appreciated!

N.
 
This is the line that gives the error

Code:
bool clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH);

comment tha out and it links fine.

Did you define the clbkLoadPanel2D function as:
Code:
bool Control_Bunker::clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH) {
// the body of the function
}

If you defined it without "Control_Bunker::" outside of the class declaration / namespace, the function isn't in the class scope, but it's global, and that's why the linker can't find it (because class is part of the function name in the mangled symbol).
 
Thanks Orb, just so you know where I am!
Went back to the ShuttlePB, and stripped it out as per the Vessel Tutorial 1 in OrbiterWiki.

The .cpp looks like this:
Code:
// ==============================================================
//                 ORBITER MODULE: Control_Bunker
//                  Part of the ORBITER SDK
//          Copyright (C) 2002-2004 Martin Schweiger
//                   All rights reserved
//
// Control_Bunker.cpp
// Control module for Control_Bunker vessel class
//
// Notes:
// This is an example for a "minimal" vessel implementation which
// only overloads the clbkSetClassCaps method to define vessel
// capabilities and otherwise uses the default VESSEL class
// behaviour.
// ==============================================================

#define STRICT
#define ORBITER_MODULE

#include "orbitersdk.h"
//#include "Instrument.h"
#include "Control_Bunker.h"

Control_Bunker::Control_Bunker (OBJHANDLE hVessel, int flightmodel)
: VESSEL3 (hVessel, flightmodel)
{

}

Control_Bunker::~Control_Bunker ()
{
}

// ==============================================================
// Overloaded callback functions
// ==============================================================

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void Control_Bunker::clbkSetClassCaps (FILEHANDLE cfg)
{


	THRUSTER_HANDLE th_main ;

	// physical vessel parameters
	SetSize (PB_SIZE);
	SetEmptyMass (PB_EMPTYMASS);
	
	SetTouchdownPoints (PB_TDP[0], PB_TDP[1], PB_TDP[2]);
	
	// propellant resources
	PROPELLANT_HANDLE hpr = CreatePropellantResource (PB_FUELMASS);

	// main engine
	th_main = CreateThruster (_V(0,0,-4.35), _V(0,0,1), PB_MAXMAINTH, hpr, PB_ISP);
	
	AddExhaust (th_main, 8, 1, _V(0,0.3,-4.35), _V(0,0,-1));

	PARTICLESTREAMSPEC exhaust_main = {
		0, 2.0, 20, 200, 0.05, 0.1, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
	};
	
	AddExhaustStream (th_main, _V(0,0.3,-5), &exhaust_main);

		// camera parameters
	SetCameraOffset (_V(0,0.8,0));

	// associate a mesh for the visual
	AddMesh ("Control_Bunker");
}

// ==============================================================
// API callback interface
// ==============================================================

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	return new Control_Bunker (hvessel, flightmodel);
}
// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (Control_Bunker*)vessel;
}

and the .h file:

// ==============================================================
// Some vessel parameters
// ==============================================================
const double PB_SIZE = 5; // mean radius [m]

const double PB_EMPTYMASS = 500.0; // empty vessel mass [kg]
const double PB_FUELMASS = 750.0; // max fuel mass [kg]
const double PB_ISP = 5e4; // fuel-specific impulse [m/s]

const VECTOR3 PB_TDP[3] = {{0,0.1,2},{-1,0.01,-1.5},{1,0.01,-1.5}}; // touchdown points [m] {0,-1.5,2},{-1,-1.5,-1.5},{1,-1.5,-1.5}

const double PB_MAXMAINTH = 3e4;

// ==============================================================
// Control_Bunker class interface
// ==============================================================

class Control_Bunker: public VESSEL3 {
public:
Control_Bunker (OBJHANDLE hVessel, int flightmodel);
~Control_Bunker ();
void clbkSetClassCaps (FILEHANDLE cfg);
static SURFHANDLE panel2dtex;

bool Control_Bunker::clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH);

MESHHANDLE hPanelMesh;
void DefineMainPanel (PANELHANDLE hPanel);
void ScalePanel (PANELHANDLE hPanel, DWORD viewW, DWORD viewH);


};
Its that clblkLoadPanel2D that is causing the problem, remove that and its a happy bunny.
What confuses me is why that function causes a problem, and DefineMainPanel and ScalePanel don't?

thanks for the help, N.
 
In the header file you need to leave the declaration this way:
Code:
bool clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH);
But you need to define your "bool Control_Bunker::clbkLoadPanel2D" function in the .cpp file.

The clbkLoadPanel2D is overriding the generic clbkLoadPanel2D virtual function defined in Orbiter, so if you declared it, you need to define it, and other functions are your own methods, and if they weren't used anywhere yet, they don't need to be defined yet.
 
Ah, the light breaks.
I messed about with an existing function?

clbkLoadPanel2D is an overload of clbkLoadPanel that is known to the Linker?

So I must? have a function defined in the .cpp file if I do this?

Many thanks, N.
 
clbkLoadPanel2D is an overload of clbkLoadPanel that is known to the Linker?
clbkLoadPanel2D is a virtual function of VESSEL2 (and its derivative) class. Virtual functions need to be defined, because they are referenced by vtable.

So I must? have a function defined in the .cpp file if I do this?
You must define the function you declared in a class that extends the class, which defined that virtual function. If you haven't declared the clbkLoadPanel2D (which is virtual), you don't need to define it.

The "void DefineMainPanel (PANELHANDLE hPanel);" and "void ScalePanel (PANELHANDLE hPanel, DWORD viewW, DWORD viewH);" aren't virtual functions, so you don't have to define them if you only declared them, but haven't used.
 
Thanks Orb, that is sort of sinking in.
Thought I could pick up where I left off last year, guess not!

Back to the keyboard.

N.
 
If you need to have clbkLoadPanel2D declared in your header file, but not actually code the body of that function, you can always define for it a simple function that returns false in the .cpp file, i.e.:
Code:
bool Control_Bunker::clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH) {
    return false;
}
 
Back
Top