Question Ranger (and other ships) from Interstellar?

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,343
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I am away for computer. But basically have a variable to tell if added or not added exhaust stream, right

Then if added and alt is above 10 del exhaust stream?

You need some variables, not all are necessary, but they really make your live easier.

Lets start at the design phase:

What you describe is a typical DFA in computer science, a deterministic finite automate, a type of state machine.

You have two states, that the customer/player will see: Particle stream visible and particle stream invisible.

You have the following transitions defined:

Initial --> Visible?
Visible: (Alt > 10) --> Invisible
Invisible: (Alt < 10) --> Visible

But since nothing really happens in each state and all important tasks actually happen during the transition, you can internally focus on the transition:

Initial -->Invisible_to_visible
Visible_to_invisible: (Alt > 10) --> Invisible_to_visible
Invisible_to_visible: (Alt < 10) --> Visible_to_invisible

So, now you have a fine design. You need one variable to track the current state and when the event happens, you execute a state transition, which also changes the variable at the end.

Now, to the implementation. You already have a state machine in your code, even if you did not make it visible.

For deleting a particle stream, you need to know which particle stream. This identification of the particle stream is the return value when you create it.

So, for each particle stream, you need a variable to identify it, so you can delete it.

Do you see the picture now?
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Ok. So like this. Smoke tells me if exhaust is on (smoke=1) or exhaust is not on (smoke=0)
Code:
	//smoke =Particle stream visible (1) and particle stream invisible(0).
	if ((alt <10) && (smoke == 0)) //alt<10 and exhaust deleted
	{
			AddExhaustStream(th_hover[0], _V(-3.421, 0, 2.43), &exhaust_hover);
			AddExhaustStream(th_hover[1], _V(3.421, 0, 2.43), &exhaust_hover);
			AddExhaustStream(th_hover[2], _V(-3.421, 0, -2.136), &exhaust_hover);
			AddExhaustStream(th_hover[3], _V(3.421, 0, -2.136), &exhaust_hover);
			smoke = 1;// exhaust added
	};

So smoke is 0 at start so do not make exhaust stream.

If smoke =0 (not Seen) and ALt<10 then add exhaust.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,343
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
You should still remember that you need the PSTREAM_HANDLE for each particle stream.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Thanks. this works. Now to get the mfd buttons and she is done:)
Code:
if ((alt <10) && (smoke == 0)) //alt<10 and exhaust deleted
	{
		hover_jet[0] = AddExhaustStream	(th_hover[0], _V(-3.421, 0, 2.43), &exhaust_hover);
		hover_jet[1] = AddExhaustStream(th_hover[1], _V(3.421, 0, 2.43), &exhaust_hover);
		hover_jet[2] = AddExhaustStream(th_hover[2], _V(-3.421, 0, -2.136), &exhaust_hover);
		hover_jet[3] = AddExhaustStream(th_hover[3], _V(3.421, 0, -2.136), &exhaust_hover);
			smoke = 1;// exhaust added
	};
	if ((alt>10) && (smoke == 1))  //alt>10 and exhausted added
	{
	//	SetThrusterGroupLevel(THGROUP_HOVER, 0.0);
		DelExhaustStream(hover_jet[0]);
		DelExhaustStream(hover_jet[1]);

		DelExhaustStream(hover_jet[2]);

		DelExhaustStream(hover_jet[3]);

		//	DelExhaustStream(th_hover[1]);
		//	DelExhaustStream(th_hover[2]);
		//	DelExhaustStream(th_hover[3]);
		//	SetThrusterGroupLevel(THGROUP_HOVER, current_thrust_hover_level);
			smoke = 0;//del exhaust streams
		};


---------- Post added 09-09-16 at 07:56 AM ---------- Previous post was 09-08-16 at 04:35 PM ----------

So is there a key that one can code to turn on/off a mfd. So like press CTRL 1 and the mfd comes on/off and is set to be only 1 mfd like surface?
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,343
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire

So is there a key that one can code to turn on/off a mfd. So like press CTRL 1 and the mfd comes on/off and is set to be only 1 mfd like surface?

I am not sure what you mean by that. Can you explain your scenario in more detail?
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Sure. I have a 2 mfd that I just want to be on/off and always surface. I know I can do that in scenario. But just wanted to know if I can by code
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Ok. On the Ranger we have 8 mfds. Not sure if mfd facing the x direction will work as far as the buttons go?

But I have 4 mfd facing the z direction. 3 of them work great. The 4th one though the sys buttom (Power, menu, Select) work. But not the function.

So I have been told I can write to the log the mouse click point to see if it is hitting the mouse. I guess I can also see if the mouse is slicking the fn buttons. Not sure how though?

Basically on our mfd code rather than a area we used the mesh.
Code:
	// COPILOT Right
	DefineMfdButtons(
		TEX_NEWRANGER17VC_MFD_DYNAMIC_05,
		AID_COPILOT_MFD_RIGHT_BTNS_FN, GRP_NEWRANGER17VC_COPILOT_MFD_RIGHT_BTNS_FN, buttonFnRect[MFD_COPILOT_RIGHT],
		AID_COPILOT_MFD_RIGHT_BTNS_SYS, GRP_NEWRANGER17VC_COPILOT_MFD_RIGHT_BTNS_SYS
		);


}

void ClassicMfd::DefineMfdButtons(
	UINT const texId,
	UINT const fuctionAreaId, UINT const functionGroupId, RECT const functionRect,
	UINT const sysAreaId, UINT const sysGroupId
	)
{
	SURFHANDLE const texDyn = oapiGetTextureHandle(meshhg_VC, texId);
	oapiVCRegisterArea(fuctionAreaId, functionRect, PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED | PANEL_MOUSE_ONREPLAY, PANEL_MAP_NONE, texDyn);
	DefineStaticClickArea(oapiMeshGroup(meshhg_VC, functionGroupId), fuctionAreaId, true);

	oapiVCRegisterArea(sysAreaId, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_ONREPLAY);
	DefineStaticClickArea(oapiMeshGroup(meshhg_VC, sysGroupId), sysAreaId, true);
}

static int get_font_height(HDC const hDC)
{
	TEXTMETRIC tm;
	if (GetTextMetrics(hDC, &tm))
	{
		return abs(tm.tmAscent);
	}

	return 5; // Wild, crazy guessing
}

void ClassicMfd::RedrawMFDButtons(SURFHANDLE const surf, int const mfd)
{
	int const btnWidth = buttonFnDim->width;
	int const btnHeight = buttonFnDim->height;
	RECT const draw_area = _R(0, 0, buttonFnRect[mfd].right - buttonFnRect[mfd].left, buttonFnRect[mfd].bottom - buttonFnRect[mfd].top);

	HDC const hDC = oapiGetDC(surf);

	SelectObject(hDC, buttonBrush);
	SetBkMode(hDC, OPAQUE);
	Rectangle(hDC, draw_area.left, draw_area.top, draw_area.right, draw_area.bottom);

	HFONT pFont = (HFONT)SelectObject(hDC, labelFont);
	SetTextColor(hDC, labelColor);
	SetTextAlign(hDC, TA_CENTER);
	int const half_font_height = get_font_height(hDC) / 2;

	char const * label;
	int const label_x_offset = (btnWidth / 2);
	int const label_y_offset = (btnHeight / 2) - buttonFnDim->marginHeight - half_font_height;
	for (int i = 0; i < 12; i++) {
		int const x = i / 6;
		int const y = i % 6;
		if (label = oapiMFDButtonLabel(mfd, i)) {
			int const xwidth = (x * btnWidth);
			int const yheight = (y * btnHeight);

			SelectObject(hDC, buttonLabelBrush);
			SetBkMode(hDC, OPAQUE);
			Rectangle(hDC,
				draw_area.left + xwidth + buttonFnDim->marginWidth,
				draw_area.top + yheight + buttonFnDim->marginHeight,
				draw_area.left + xwidth + btnWidth - buttonFnDim->marginWidth,
				draw_area.top + yheight + btnHeight - buttonFnDim->marginHeight
				);
			SetBkMode(hDC, TRANSPARENT);
			TextOut(hDC, draw_area.left + xwidth + label_x_offset, draw_area.top + yheight + label_y_offset, label, strlen(label));
		}
		else break;
	}

	SelectObject(hDC, pFont);
	oapiReleaseDC(surf, hDC);
}

void ClassicMfd::DefineStaticClickArea(MESHGROUP const * const gr, int const id, bool const rect, const VECTOR3& revert, const VECTOR3& maxShift)
{
	float minX, maxX, minY, maxY, minZ, maxZ, x, y, z;
	minX = minY = minZ = 1000.0f;
	maxX = maxY = maxZ = -1000.0f;
	for (DWORD i = 0; i < gr->nVtx; i++) {
		x = gr->Vtx[i].x;
		y = gr->Vtx[i].y;
		z = gr->Vtx[i].z;
		if (x < minX) minX = x;
		if (y < minY) minY = y;
		if (z < minZ) minZ = z;
		if (x > maxX) maxX = x + (float)maxShift.x;
		if (y > maxY) maxY = y + (float)maxShift.y;
		if (z > maxZ) maxZ = z + (float)maxShift.z;
	}
	if (rect) {
		VECTOR3 p1 = _V(revert.x > 0 ? maxX : minX, revert.y > 0 ? minY : maxY, revert.z > 0 ? minZ : maxZ);
		VECTOR3 p2 = _V(revert.x > 0 ? minX : maxX, revert.y > 0 ? minY : maxY, revert.z > 0 ? minZ : maxZ);
		VECTOR3 p3 = _V(revert.x > 0 ? maxX : minX, revert.y > 0 ? maxY : minY, revert.z > 0 ? maxZ : minZ);
		VECTOR3 p4 = _V(revert.x > 0 ? minX : maxX, revert.y > 0 ? maxY : minY, revert.z > 0 ? maxZ : minZ);
		oapiVCSetAreaClickmode_Quadrilateral(id, p1, p2, p3, p4);
	}
	else {
		double distX = Distance(minX, maxX);
		double distY = Distance(minY, maxY);
		double distZ = Distance(minZ, maxZ);
		VECTOR3 center = _V(minX + distX / 2.0f, minY + distY / 2.0f, minZ + distZ / 2.0f);
		double rad = max(distX, max(distY, distZ)) / 2.0;
		oapiVCSetAreaClickmode_Spherical(id, center, rad);
	}
}

Since it is based off the mesh I tied switching the mesh group number. I could get the functions to work with the "wrong" mesh group but not the correct one.
 
Last edited:

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
So how can I see where the mouse click is?

Basically rather than measured vectors we are using the mesh group.
Code:
DefineMfdButtons(
		TEX_NEWRANGER21VC_MFD_DYNAMIC_8,
		AID_COPILOT_MFD_RIGHT_BTNS_FN, GRP_NEWRANGER21VC_COPILOT_MFD_RIGHT_BTNS_FN, buttonFnRect[MFD_COPILOT_RIGHT],
		AID_COPILOT_MFD_RIGHT_BTNS_SYS, GRP_NEWRANGER21VC_COPILOT_MFD_RIGHT_BTNS_SYS
		);

So the FN buttons are in
Code:
#define GRP_NEWRANGER21VC_COPILOT_MFD_RIGHT_BTNS_FN	 	63

Code:
void ClassicMfd::DefineMfdButtons(
	UINT const texId,
	UINT const fuctionAreaId, UINT const functionGroupId, RECT const functionRect,
	UINT const sysAreaId, UINT const sysGroupId
	)
{
	SURFHANDLE const texDyn = oapiGetTextureHandle(meshhg_VC, texId);
	oapiVCRegisterArea(fuctionAreaId, functionRect, PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED | PANEL_MOUSE_ONREPLAY, PANEL_MAP_NONE, texDyn);
	DefineStaticClickArea(oapiMeshGroup(meshhg_VC, functionGroupId), fuctionAreaId, true);

	oapiVCRegisterArea(sysAreaId, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_ONREPLAY);
	DefineStaticClickArea(oapiMeshGroup(meshhg_VC, sysGroupId), sysAreaId, true);
}

So based on the mesh group if clicked it works the mfd. But all work but the copilot right fn.

---------- Post added 09-17-16 at 07:10 AM ---------- Previous post was 09-16-16 at 05:19 PM ----------

No clue.

I do get a warning in compiling;
c:\orbiter100830\orbitersdk\samples\testranger\RANGER.h(103): warning C4227: anachronism used : qualifiers on reference are ignored

Code:
	bool VCMouseEvent(int const id, int const event, VECTOR3& const p);
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,343
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I do get a warning in compiling;
c:\orbiter100830\orbitersdk\samples\testranger\RANGER.h(103): warning C4227: anachronism used : qualifiers on reference are ignored

Code:
    bool VCMouseEvent(int const id, int const event, VECTOR3& const p);

Remove the const at VECTOR3& or invert the order to "const VECTOR3 &"
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Thanks. I have this:
Code:
	bool VCMouseEvent(int const id, int const event, VECTOR3&  p);

but still the issue with the mfd. It is like it is not in the right area.

---------- Post added 09-18-16 at 05:07 AM ---------- Previous post was 09-17-16 at 08:46 AM ----------

I started running the debugger.

When I click on the sys i get this:
Code:
		aid	8	const int
		event	1	const int
-		p	{data=0x00aefe34 {0.033084739530499618, 0.35614239193941444, 0.00000000000000000} x=0.033084739530499618 ...}	const VECTOR3 &

But if those are coordinates. It doesn't match the mesh.
I get nothing for processing

case AID_COPILOT_NEW_MFD_RIGHT_BTNS_FN:

Code:
bool ClassicMfd::HandleMouseEvent(int const aid, int const event, VECTOR3 const &p)
{
	switch (aid) {
	case AID_PILOT_MFD_LEFT_BTNS_FN:
		return ProcessMfdFnButton(MFD_PILOT_LEFT, event, p);
	case AID_PILOT_MFD_LEFT_BTNS_SYS:
		return ProcessMfdSysButton(MFD_PILOT_LEFT, event, p);

	case AID_PILOT_MFD_RIGHT_BTNS_FN:
		return ProcessMfdFnButton(MFD_PILOT_RIGHT, event, p);
	case AID_PILOT_MFD_RIGHT_BTNS_SYS:
		return ProcessMfdSysButton(MFD_PILOT_RIGHT, event, p);

	case AID_COPILOT_MFD_LEFT_BTNS_FN:
		return ProcessMfdFnButton(MFD_COPILOT_LEFT, event, p);
	case AID_COPILOT_MFD_LEFT_BTNS_SYS:
		return ProcessMfdSysButton(MFD_COPILOT_LEFT, event, p);

	case AID_COPILOT_NEW_MFD_RIGHT_BTNS_FN:
		return ProcessMfdFnButton(MFD_COPILOT_RIGHT, event, p);
	case AID_COPILOT_MFD_RIGHT_BTNS_SYS:
		return ProcessMfdSysButton(MFD_COPILOT_RIGHT, event, p);

	}

	return false;
}
Code:
#define AID_PILOT_MFD_LEFT_BTNS_FN 1
#define AID_PILOT_MFD_LEFT_BTNS_SYS 2
#define AID_PILOT_MFD_RIGHT_BTNS_FN 3
#define AID_PILOT_MFD_RIGHT_BTNS_SYS 4
#define AID_COPILOT_MFD_LEFT_BTNS_FN 5
#define AID_COPILOT_MFD_LEFT_BTNS_SYS 6
#define AID_COPILOT_NEW_MFD_RIGHT_BTNS_FN 7
#define AID_COPILOT_MFD_RIGHT_BTNS_SYS 8
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,343
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
The coordinates are relative to your clickable area definition. If you use a quad, its the relative coordinates inside a rectangle, if you use a spherical definition, its the radius relative to the reference position.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Thanks.
I guess I need to figure out why the mouse click doesn't trigger the
AID_COPILOT_NEW_MFD_RIGHT_BTNS_FN

success:::
 
Last edited:

BenSisko

Donator
Donator
Joined
Feb 18, 2008
Messages
420
Reaction score
45
Points
28
Well, a new issue here. Gattispilot and Co. have modeled the ships of Interstellar; the Endurance, the Ranger, and the Lander. We're having an issue with the Lander. The Lander is designed to reenter Earth-like planets inverted (cargo pallets are attached to undersurface of the Lander so inverted reentry protects the cargo). As it stands now, using BaseSync MFD and Glideslope 2 MFD to guide reentry, the Lander's Lift/Drag performance is erratic. We need suggestions on coding the aerodynamic properties of the ship.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
This is what we have. It is based off Shuttle-A
Code:
void Lander_MomentCoeff(double aoa, double M, double Re, double *cl, double *cm, double *cd)
{
	int i;
	const int nabsc = 7;
	static const double AOA[nabsc] = { -180 * RAD, -90 * RAD, -30 * RAD, 0 * RAD, 60 * RAD, 90 * RAD, 180 * RAD };
	static const double CL[nabsc] = { 0, 0, -0.004, 0, 0.008, 0, 0 };
	static const double CM[nabsc] = { 0, 0, 0.0014, 0, -0.0012, 0, 0 };

	for (i = 0; i < nabsc - 1 && AOA[i + 1] < aoa; i++);
	double f = (aoa - AOA[i]) / (AOA[i + 1] - AOA[i]);
	*cl = CL[i] + (CL[i + 1] - CL[i]) * f;  // aoa-dependent lift coefficient
	*cm = CM[i] + (CM[i + 1] - CM[i]) * f;  // aoa-dependent moment coefficient
	double saoa = sin(aoa);
	double pd = 0.045 + 0.4*saoa*saoa;  // profile drag
	*cd = pd + oapiGetInducedDrag(*cl, 0.1, 0.7) + oapiGetWaveDrag(M, 0.75, 1.0, 1.1, 0.04);
	// profile drag + (lift-)induced drag + transonic/supersonic wave (compressibility) drag
}
Code:
void LANDER6::clbkSetClassCaps(FILEHANDLE cfg)
{
	SetSize(11);
	SetEmptyMass(11000.0);
	SetCW(0.3, 0.3, 0.6, 0.9);
	SetWingAspect(1.7);
	SetWingEffectiveness(2.5);
	SetCrossSections(_V(71.59, 206.57, 50.58));
	SetRotDrag(_V(3.5, 3.5, 3.5));
	if (GetFlightModel() >= 1) {
		SetPitchMomentScale(1e-4);
		SetBankMomentScale(1e-4);
	}
	SetPMI(_V(32.49, 38.14, 23.67));
	SetTrimScale(0.08);
	SetCameraOffset(_V(0, 3, 10.1));
	SetTouchdownPoints(_V(0, -.003, 5.7), _V(-3.448, -.003, -5.0), _V(3.448, -.003, -5.0));;
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
So we have thought to make it like an inverted Delta Glider.

I can add the DG specs. But how to I make it inverted.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,343
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
So we have thought to make it like an inverted Delta Glider.

I can add the DG specs. But how to I make it inverted.

Why inverted? Also why aerodynamic at all, it looks like a brick.
 

BenSisko

Donator
Donator
Joined
Feb 18, 2008
Messages
420
Reaction score
45
Points
28
Even a brick has predictable lift/drag characteristics at hypersonic speeds. The problem we're having is that our current model of the Lander has erratic lift/drag performance. The ship is designed to renter inverted. As you vary pitch, the lift/drag response doesn't allow you fly a reentry profile. We need to create an aerodynamic model for the Lander that will allow you to fly reentry.
 

hypersonic

Ancient Starship
Joined
Feb 12, 2008
Messages
81
Reaction score
0
Points
6
Location
London
Hi gattispilot
Firstly i do apologise. Shortly after i started this thread a close family member was diagnosed with a serious illness, and alas subsequently passed away. A difficult time for all, which has kept me away from many things, including Orbiter.
However I have to say you have done absolutely fantastic work and i applaud you and all the contributors in helping to make the ships from Interstellar an Orbiter reality!!
Very Well Done!!!
I'm more than happy to aid in testing, if needed in a sparkly new install of Orbiter 2016!.
Hope you're well too.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,690
Points
203
Location
Dallas, TX
Thanks. And sorry. We are still trying to get some coding issues fixed. But we do have the Endurance, Ranger and Lander. All seem to function in 2016 except for the Ummu part.
 

jgrillo2002

Conservative Pioneer
Addon Developer
Joined
Mar 17, 2008
Messages
755
Reaction score
17
Points
33
Location
New York State
Thanks. And sorry. We are still trying to get some coding issues fixed. But we do have the Endurance, Ranger and Lander. All seem to function in 2016 except for the Ummu part.
Question. will this addon be reverse compatible with the 2010 version of Orbiter?
 
Top