Coding a Lunar Lander from the ground up: Making your VC Interactive

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
PART 14: Making the Cockpit Interactive

So last we left off we had a cockpit and a shiny cockpit control class that didn't actually do anything. Now it's time to do stuff.

VC displays and user inputs are handled by "Active areas" that are registered when the VC is loaded. To generate these active area s I have created a function called "RegisterActiveAreas" in our cockpit control class. (See part 13) this function is a void and takes a single VECTOR3 variable called "ofs" as an argument. If you look at the top of our "clbkLoadVC" back in the vessel class itself I think you can figure out what it's for.

Anyway, in order to function each active area needs to be assigned an index value and a location within the cockpit. The index value is a base 8 intiger and the location a VECTOR3. We could declare these Individually but for the sake of my sanity and because there are a whole lot of active areas in our cockpit I will be putting as much as I can into the Cockpit header file.

Observe...
Code:
// ==============================================================
// Active Area Definitions
// ==============================================================

// Multi Function Display indexes
#define CmdMFD					00		// Primary (Panel 4) MFD

// Main Panel Displays and Gauges 
#define AID_LCD_DATETIME		0001	// Main panel digital clock
#define AID_LCD_FUEL			0002	// Main engine digital propellant readout
#define AID_LCD_RCS				0003	// RCS thruster digital propellant readout
#define AID_LCD_DELTAV			0004	// dV digital display
#define AID_GAUGE_ALTRANGE		0005	// Altitude/Range indicator
#define AID_GAUGE_RANGERATE		0006	// Range Rate indicator
#define AID_GAUGE_VACC			0007	// Vertical acceleration (T/W) indicator

#define AID_CAUTIONADVISORY		0010	// Caution/Warning/Advisory (CWA) Display
#define AID_P1_MASTERCAUTION	0011	// Commander's master Caution Indicator
#define AID_P2_MASTERCAUTION	0012	// Pilot's master Caution Indicator
#define AID_P1_XPOINTER			0013	// Commander's ground-speed/slip indicator
#define AID_P2_XPOINTER			0014	// Pilot's ground-speed/slip indicator
#define AID_P1_ADIBALL			0015	// Commander's Attitude/Direction indicator
#define AID_P2_ADIBALL			0016	// Pilot's Attitude/Direction indicator

// EVA Hatch
#define AID_EVAHANDLE_OPEN		0020
#define AID_EVAHANDLE_CLOSE		0021
#define AID_EVA_EGRESS			0022

// VC Active Areas (Panel 1)
#define AID_PANEL_1				((id >= 0100) && (id <= 0124))
#define AID_SWITCH_P1_00		0100
#define AID_SWITCH_P1_01		0101
#define AID_SWITCH_P1_02		0102
#define AID_SWITCH_P1_03		0103	// Engine arm
#define AID_SWITCH_P1_04		0104	
#define AID_SWITCH_P1_05		0105	// Throttle Control Mode
#define AID_SWITCH_P1_06		0106	
#define AID_SWITCH_P1_07		0107	// CDR's ACA prop

#define AID_SWITCH_P1_08		0110	// Manual control select
#define AID_SWITCH_P1_09		0111
#define AID_SWITCH_P1_10		0112
#define AID_SWITCH_P1_11		0113	// Ascent He REG 1
#define AID_SWITCH_P1_12		0114	// Descent He REG 1
#define AID_SWITCH_P1_13		0115	// Ascent He REG 2
#define AID_SWITCH_P1_14		0116	// Descent He REG 2
#define AID_SWITCH_P1_15		0117

#define AID_SWITCH_P1_16		0120
#define AID_SWITCH_P1_17		0121	// Guidance control
#define AID_SWITCH_P1_18		0122	// Altimeter mode select
#define AID_SWITCH_P1_19		0123
#define AID_DIAL_P1_00			0124

#define AID_BTN_P1_ABORT		0007	// Docking latch release button
#define AID_BTN_P1_ABORTSTAGE	0010	// Abort Stage button

// VC Active Areas (Panel 2)
#define AID_PANEL_2				((id >= 0200) && (id <= 0226))
#define AID_SWITCH_P2_00		0201	// RCS "A" propellant shut off valve
#define AID_SWITCH_P2_01		0202	// RCS "A" quad-1
#define AID_SWITCH_P2_02		0203	// RCS "A" quad-2
#define AID_SWITCH_P2_03		0204	// RCS A/B cross-feed valve
#define AID_SWITCH_P2_04		0205	// RCS "A" oxidizer shut off valve
#define AID_SWITCH_P2_05		0206	// RCS "A" quad-4
#define AID_SWITCH_P2_06		0207	// RCS "A" quad-3
#define AID_SWITCH_P2_07		0210	// RCS "A" ascent tank cross-feed valve
#define AID_SWITCH_P2_08		0211	// RCS "B" propellant shut off valve
#define AID_SWITCH_P2_09		0212	// RCS "B" quad-1
#define AID_SWITCH_P2_10		0213	// RCS "B" quad-2
#define AID_SWITCH_P2_11		0214	// RCS "B" oxidizer shut off valve
#define AID_SWITCH_P2_12		0215	// RCS "B" quad-4
#define AID_SWITCH_P2_13		0216	// RCS "B" quad-3
#define AID_SWITCH_P2_14		0217	// RCS "B" ascent tank cross-feed valve
#define AID_SWITCH_P2_15		0220	// LMP's ACA prop
#define AID_SWITCH_P2_16		0221	// ADI Rate Scale
#define AID_SWITCH_P2_17		0222

#define AID_DIAL_P2_00			0223
#define AID_DIAL_P2_01			0224
#define AID_DIAL_P2_02			0225
#define AID_DIAL_P2_03			0226

// VC Active Areas (Panel 3)
#define AID_PANEL_3				((id >= 0300) && (id <= 0337))
#define AID_SWITCH_P3_01		0301	// Engine gimbal
#define AID_SWITCH_P3_02		0302	// Command overide
#define AID_SWITCH_P3_03		0303
#define AID_SWITCH_P3_04		0304
#define AID_SWITCH_P3_05		0305
#define AID_SWITCH_P3_06		0306	// Dead band select
#define AID_SWITCH_P3_07		0307	// Pitch control mode
#define AID_SWITCH_P3_09		0310
#define AID_SWITCH_P3_10		0311	// Roll control mode
#define AID_SWITCH_P3_12		0312	// Event timer start
#define AID_SWITCH_P3_13		0313	// Yaw control mode
#define AID_SWITCH_P3_14		0314
#define AID_SWITCH_P3_15		0315	// Event timer mode
#define AID_SWITCH_P3_16		0316	
#define AID_SWITCH_P3_17		0317	// Quad 1 heater
#define AID_SWITCH_P3_18		0320	// Quad 2 heater
#define AID_SWITCH_P3_19		0321	// Event timer slew (min)
#define AID_SWITCH_P3_20		0322	// Quad 4 heater
#define AID_SWITCH_P3_21		0323	// Quad 3 heater
#define AID_SWITCH_P3_22		0324	// Event timer slew (sec)
#define AID_SWITCH_P3_23		0325
#define AID_SWITCH_P3_24		0326
#define AID_SWITCH_P3_25		0327

#define AID_DIAL_P3_00			0332
#define AID_DIAL_P3_01			0333
#define AID_DIAL_P3_02			0334	// Attitude control mode
#define AID_DIAL_P3_03			0335
#define AID_DIAL_P3_04			0336
#define AID_DIAL_P3_05			0337

// VC Active Areas (Panel 4)
#define AID_PANEL_4				((id >= 0400) && (id <= 0404))
#define AID_SWITCH_P4_00		0401	// CDR's RCS vernier
#define AID_SWITCH_P4_01		0402	// CDR's RCS mode select
#define AID_SWITCH_P4_02		0403	// LMP's RCS vernier
#define AID_SWITCH_P4_03		0404	// LMP's RCS mode select

#define AID_MFD_P4_LBUTTONS		0411	// MFD soft-keys (Left side)
#define AID_MFD_P4_RBUTTONS		0412	// MFD soft-keys (Right side)
#define AID_MFD_P4_PWR			0413	// MFD 'Power' button
#define AID_MFD_P4_SEL			0414	// MFD 'Select' button
#define AID_MFD_P4_MNU			0415	// MFD 'Menu' button

// VC Active Areas (Panel 5)
#define AID_PANEL_5				((id >= 0500) && (id <= 0516))
#define AID_SWITCH_P5_00		0501	// Mission timer mode
#define AID_SWITCH_P5_01		0502	
#define AID_SWITCH_P5_02		0503	// Mission timer slew (hrs)
#define AID_SWITCH_P5_03		0504	
#define AID_SWITCH_P5_04		0505	// Mission timer slew (min)
#define AID_SWITCH_P5_05		0506
#define AID_SWITCH_P5_06		0507	// Mission timer slew (sec)
#define AID_SWITCH_P5_07		0510

#define AID_BTN_P5_XTRANS		0511	// Ullage burn
#define AID_BTN_P5_START		0512	// Start engine
#define AID_BTN_P5_STOP			0513	// Kill thrust

#define AID_DIAL_P5_00			0514	// Floodlights
#define AID_DIAL_P5_01			0515	// Panel lights
#define AID_DIAL_P5_02			0516	// Displays

// VC Active Areas (Panel 6)
#define AID_PANEL_6				((id >= 0600) && (id <= 0626))
#define AID_SWITCH_P6_00		0600	// Gyro 1
#define AID_SWITCH_P6_01		0601	// Gyro 1
#define AID_SWITCH_P6_02		0602	// Gyro 2
#define AID_SWITCH_P6_03		0603	// Gyro 2
#define AID_SWITCH_P6_04		0604	// Gyro 1
#define AID_SWITCH_P6_05		0605	// Gyro 1
#define AID_SWITCH_P6_06		0606	// Gyro 2
#define AID_SWITCH_P6_07		0607	// Gyro 2

#define AID_SWITCH_P6_08		0610	// Gyro 1
#define AID_SWITCH_P6_09		0611	// Gyro 1
#define AID_SWITCH_P6_10		0612	// Gyro 2
#define AID_SWITCH_P6_11		0613	// Gyro 2

#define AID_DIAL_P6_00			0623	// Gyro 1, Ref Frame select
#define AID_DIAL_P6_01			0624	// Gyro 2, Ref Frame select
#define AID_DIAL_P6_02			0625	// Gyro 1, Target mode select
#define AID_DIAL_P6_03			0626	// Gyro 2, Target mode select

// Projection mode
	// Primary Axis 
	// Set/Clear offset
	// Nav Channel select

// VC Active Areas (Panel 8)
#define AID_PANEL_8				((id >= 1000) && (id <= 1023))
#define AID_SWITCH_P8_00		1001	
#define AID_SWITCH_P8_01		1002	
#define AID_SWITCH_P8_02		1003	
#define AID_SWITCH_P8_03		1004	 
#define AID_SWITCH_P8_04		1005
#define AID_SWITCH_P8_05		1006
#define AID_SWITCH_P8_06		1007
#define AID_SWITCH_P8_07		1008
#define AID_SWITCH_P8_08		1009
#define AID_SWITCH_P8_09		1010
#define AID_SWITCH_P8_10		1011
#define AID_SWITCH_P8_11		1012
#define AID_SWITCH_P8_12		1013
#define AID_SWITCH_P8_13		1014
#define AID_SWITCH_P8_14		1015
#define AID_SWITCH_P8_15		1016
#define AID_SWITCH_P8_16		1017
#define AID_SWITCH_P8_17		1018
#define AID_SWITCH_P8_18		1019
#define AID_SWITCH_P8_19		1020
#define AID_SWITCH_P8_20		1021
#define AID_SWITCH_P8_21		1022
#define AID_SWITCH_P8_22		1023

// VC Active Areas (Panel 12)
#define AID_PANEL_12			((id >= 1200) && (id <= 1226))
#define AID_SWITCH_P12_00		1200	
#define AID_SWITCH_P12_01		1201	
#define AID_SWITCH_P12_02		1202	
#define AID_SWITCH_P12_03		1203	 
#define AID_SWITCH_P12_04		1204
#define AID_SWITCH_P12_05		1205
#define AID_SWITCH_P12_06		1206
#define AID_SWITCH_P12_07		1207
#define AID_SWITCH_P12_08		1208
#define AID_SWITCH_P12_09		1209
#define AID_SWITCH_P12_10		1210
#define AID_SWITCH_P12_11		1211
#define AID_SWITCH_P12_12		1212
#define AID_SWITCH_P12_13		1213
#define AID_SWITCH_P12_14		1214
#define AID_SWITCH_P12_15		1215
#define AID_SWITCH_P12_16		1216
#define AID_SWITCH_P12_17		1217
#define AID_SWITCH_P12_18		1218
#define AID_SWITCH_P12_19		1219
#define AID_SWITCH_P12_20		1220
#define AID_SWITCH_P12_21		1221
#define AID_SWITCH_P12_22		1222

#define AID_DIAL_P12_00			1223
#define AID_DIAL_P12_01			1224
#define AID_DIAL_P12_02			1225
#define AID_DIAL_P12_03			1226

// VC Active Areas (Panel 14)
#define AID_PANEL_14			((id >= 1400) && (id <= 1416))
#define AID_SWITCH_P14_00		1400	
#define AID_SWITCH_P14_01		1401	
#define AID_SWITCH_P14_02		1402	
#define AID_SWITCH_P14_03		1403	
#define AID_SWITCH_P14_04		1404	
#define AID_SWITCH_P14_05		1405	
#define AID_SWITCH_P14_06		1406	
#define AID_SWITCH_P14_07		1407	
#define AID_SWITCH_P14_08		1408	
#define AID_SWITCH_P14_09		1409	
#define AID_SWITCH_P14_10		1410	
#define AID_SWITCH_P14_11		1411	
#define AID_SWITCH_P14_12		1412	
#define AID_SWITCH_P14_13		1413	
#define AID_SWITCH_P14_14		1414	
#define AID_SWITCH_P14_15		1415

#define AID_DIAL_P14_00			1416

// ==============================================================
// VC Constants
// ==============================================================

const double P1_TILT	= 8*RAD;
const double P2_TILT	= 8*RAD;
const double P3_TILT	= 35*RAD;
const double P4_TILT	= 45*RAD;
const double P6_TILT	= 10*RAD;
const double P12_TILT	= 20*RAD;
const double P14_TILT	= 25*RAD;

// Number of switches on each panel
const int	 P1_NSWITCH		= 20;
const int	 P2_NSWITCH		= 18;
const int	 P3_NSWITCH		= 23;
const int	 P4_NSWITCH		= 4;
const int	 P5_NSWITCH		= 8;
const int	 P6_NSWITCH		= 12;
const int	 P8_NSWITCH		= 22;
const int	 P12_NSWITCH	= 22;
const int	 P14_NSWITCH	= 16;

// Number of dials/thumbwheels
const int	 P1_NDIAL		= 1;
const int	 P2_NDIAL		= 4;
const int	 P3_NDIAL		= 6;
const int	 P4_NDIAL		= 0;
const int	 P5_NDIAL		= 1;
const int	 P6_NDIAL		= 4;
const int	 P8_NDIAL		= 0;
const int	 P12_NDIAL		= 4;
const int	 P14_NDIAL		= 1;

// Dial rotation axises
const VECTOR3	P1_DIAL_AXIS	= { 0.00, sin(P1_TILT),-cos(P1_TILT)};
const VECTOR3	P2_DIAL_AXIS	= { 0.00, sin(P2_TILT),-cos(P2_TILT)};
const VECTOR3	P3_DIAL_AXIS	= { 0.00, cos(P3_TILT),-cos(P3_TILT)};	
const VECTOR3	P6_DIAL_AXIS	= { 0.00, cos(P6_TILT),-sin(P6_TILT)};	
const VECTOR3	P12_DIAL_AXIS	= {-sin(P12_TILT), cos(P12_TILT), 0.00};
const VECTOR3	P14_DIAL_AXIS	= { sin(P14_TILT), cos(P14_TILT), 0.00};

// ==============================================================
// Positions of active areas in VC mesh
// ==============================================================

const VECTOR3	ADI_BALL_POS[2]			= { {-0.29190, 0.63346, 1.76486}, { 0.30211, 0.63346, 1.76486}};
const VECTOR3	VC_HUD_POS				= {-0.59, 0.975,-1.12353};
const VECTOR3	MASTERCAUTION_POS[2]	= { {-0.41025, 0.68624, 1.70677}, { 0.42073, 0.69283, 1.70771}};
const VECTOR3	UNDOCK_BTN_POS			= {-0.09360, 0.53426, 1.68610};
const VECTOR3	ABORTSTAGE_BTN_POS		= {-0.04435, 0.53426, 1.68610};
const VECTOR3	XTRANS_BTN_POS			= {-0.61200, 0.02649, 1.46188};
const VECTOR3	START_BTN_POS			= {-0.68256, 0.03258, 1.46172};
const VECTOR3	STOP_BTN_POS			= {-0.68256, 0.04126, 1.51096};
const VECTOR3	MFD_POS					= { 0.00000, 0.10972, 1.44827};

// MFD buttons (relative to MFD)
const VECTOR3 MFD_BUTTON_POS[11] = {
	{-0.11331, 0.06884,-0.01354}, {-0.09703, 0.06884,-0.01354}, {-0.11331,-0.07099,-0.01354}, {-0.09703,-0.07099,-0.01354}, // Quadrilateral describing left side soft-keys
	{ 0.09703, 0.06884,-0.01354}, { 0.11331, 0.06884,-0.01354}, { 0.09703,-0.07099,-0.01354}, { 0.11331,-0.07099,-0.01354}, // Quadrilateral describing right side soft-keys
	{-0.07291,-0.09406,-0.01354}, { 0.05361,-0.09406,-0.01354}, { 0.07337,-0.09406,-0.01354} };								// Position of Power, Select, and Menu buttons 

// Panel 1 Toggle-switchs
const VECTOR3 P1_TOGGLE_POS[P1_NSWITCH] = { 
	{-0.41112, 0.63679, 1.69711}, {-0.41112, 0.58858, 1.69117}, {-0.35903, 0.51596, 1.68097}, {-0.33970, 0.41121, 1.66625}, 
	{-0.31091, 0.51596, 1.68097}, {-0.31091, 0.45853, 1.67290}, {-0.29446, 0.41121, 1.66625}, {-0.26431, 0.51596, 1.68097}, 
	{-0.26431, 0.45853, 1.67290}, {-0.26039, 0.41121, 1.66625}, {-0.23584, 0.74792, 1.71273}, {-0.22377, 0.48943, 1.67724}, 
	{-0.22377, 0.41121, 1.66625}, {-0.17579, 0.48943, 1.67724}, {-0.17579, 0.41121, 1.66625}, {-0.14838, 0.47650, 1.67542}, 
	{-0.13043, 0.41994, 1.66747}, {-0.04043, 0.69083, 1.70554}, {-0.04043, 0.64232, 1.69873}, {-0.04043, 0.59233, 1.69170}};

// Panel 1 Dial
const VECTOR3 P1_DIAL_POS[P1_NDIAL] = { {-0.06803, 0.45938, 1.67554}};

// Panel 2 Toggle-switchs
const VECTOR3 P2_TOGGLE_POS[P2_NSWITCH] = { 
	{ 0.05041, 0.76698, 1.71625}, { 0.05041, 0.67718, 1.70362}, { 0.05041, 0.59878, 1.69261}, { 0.05098, 0.51056, 1.68021}, { 0.09446, 0.76698, 1.71625}, 
	{ 0.09446, 0.67718, 1.70362}, { 0.09446, 0.59878, 1.69261}, { 0.12440, 0.51056, 1.68021}, { 0.13811, 0.76698, 1.71625}, { 0.13811, 0.67718, 1.70362}, 
	{ 0.13811, 0.59878, 1.69261}, { 0.18217, 0.76698, 1.71625}, { 0.18217, 0.67718, 1.70362}, { 0.18217, 0.59878, 1.69261}, { 0.17825, 0.51056, 1.68021},
	{ 0.17825, 0.45658, 1.67262}, { 0.42048, 0.64216, 1.69870}, { 0.42048, 0.58858, 1.69117}};

// Panel 2 Dials
const VECTOR3 P2_DIAL_POS[P2_NDIAL] = {
	{ 0.05703, 0.45057, 1.67430}, { 0.24710, 0.49405, 1.68041}, { 0.24710, 0.42250, 1.67036}, { 0.36027, 0.45827, 1.67538}};

// Panel 3 Toggle-switchs
const VECTOR3 P3_TOGGLE_POS[P3_NSWITCH] = {
	{-0.35652, 0.32535, 1.62434}, {-0.36395, 0.28302, 1.59471}, {-0.31776, 0.32535, 1.62434}, {-0.31776, 0.28302, 1.59471}, 
	{-0.25709, 0.26603, 1.58281}, {-0.11335, 0.32744, 1.62581}, {-0.11335, 0.28496, 1.59606}, /*{-0.11335, 0.23648, 1.56212}, */
	{-0.06036, 0.32744, 1.62581}, {-0.06036, 0.28496, 1.59606}, /*{-0.06036, 0.23648, 1.56212},*/ {-0.00681, 0.32744, 1.62581}, 
	{-0.00681, 0.28496, 1.59606}, {-0.00681, 0.23648, 1.56212}, { 0.10519, 0.32744, 1.62581}, { 0.13944, 0.32744, 1.62581}, 
	{ 0.13944, 0.28127, 1.59348}, { 0.13944, 0.23958, 1.56429}, { 0.17233, 0.32744, 1.62581}, { 0.17233, 0.28127, 1.59348}, 
	{ 0.17233, 0.23958, 1.56429}, { 0.20522, 0.32744, 1.62581}, { 0.24006, 0.32744, 1.62581}, { 0.24006, 0.29890, 1.60583}, 
	{ 0.35709, 0.23510, 1.56115}
	};
	
// Panel 3 Dials
const VECTOR3 P3_DIAL_POS[P3_NDIAL] = { 
	{-0.33425, 0.23079, 1.56118}, {-0.19012, 0.24194, 1.56899}, {-0.08162, 0.23373, 1.56324}, { 0.06008, 0.24099, 1.56833}, 
	{ 0.26664, 0.23420, 1.56357}, { 0.30563, 0.29777, 1.60808}
	};

// Panel 4 Toggle-switchs
const VECTOR3 P4_TOGGLE_POS[P4_NSWITCH] = {
	{-0.12900, 0.14776, 1.48380}, {-0.12900, 0.08487, 1.42090}, { 0.13500, 0.14776, 1.48380}, { 0.13500, 0.08487, 1.42090}
	};

// Panel 5 Toggle-switchs
const VECTOR3 P5_TOGGLE_POS[P5_NSWITCH] = {
	{-0.59670, 0.03450, 1.49293}, {-0.55200, 0.02374, 1.43190}, {-0.54173, 0.03450, 1.49293}, {-0.51697, 0.02374, 1.43190},
	{-0.49969, 0.03450, 1.49293}, {-0.48194, 0.02374, 1.43190}, {-0.45762, 0.03450, 1.49293}, {-0.44691, 0.02374, 1.43190},
	};

// Panel 6 Toggle-switchs
const VECTOR3 P6_TOGGLE_POS[P6_NSWITCH] = {
	{ 0.64043, 0.03879, 1.51246}, { 0.64043, 0.03011, 1.46319}, { 0.64043, 0.02092, 1.41107}, { 0.64043, 0.01223, 1.36180},
	{ 0.67543, 0.03879, 1.51246}, { 0.67543, 0.03011, 1.46319}, { 0.67543, 0.02092, 1.41107}, { 0.67543, 0.01223, 1.36180},
	{ 0.71042, 0.03879, 1.51246}, { 0.71042, 0.03011, 1.46319}, { 0.71042, 0.02092, 1.41107}, { 0.71042, 0.01223, 1.36180},
	};

// Panel 6 Dials
const VECTOR3 P6_DIAL_POS[P6_NDIAL] = {
	{ 0.49704, 0.03177, 1.49183}, { 0.49704, 0.01389, 1.39044}, { 0.58025, 0.03177, 1.49183}, { 0.58025, 0.01389, 1.39044}
	};

// Panel 8 Toggle-switchs
const VECTOR3 P8_TOGGLE_POS[P8_NSWITCH] = { 
	{-1.07517, 0.18985, 1.04111}, {-1.07517, 0.18985, 1.07512}, {-0.98428, 0.15676, 1.08001}, {-1.09473, 0.19697, 1.11613},
	{-0.98428, 0.15676, 1.11001}, {-1.04353, 0.17833, 1.18348}, {-0.98996, 0.15883, 1.18348}, {-1.09335, 0.19646, 1.21348},
	{-1.04353, 0.17833, 1.21348}, {-1.09335, 0.19646, 1.24348}, {-1.04353, 0.17833, 1.24348}, {-0.99655, 0.16123, 1.24348},
	{-1.09335, 0.19646, 1.27348}, {-1.04353, 0.17833, 1.27348}, {-0.99655, 0.16123, 1.27348}, {-1.10953, 0.20235, 1.35700},
	{-1.02496, 0.17157, 1.35700}, {-1.10953, 0.20235, 1.39700}, {-1.02496, 0.17157, 1.39700}, {-1.07194, 0.18867, 1.44199},
	{-1.07194, 0.18867, 1.48199}, {-0.98159, 0.15579, 1.49572}
	};

// Panel 12 Toggle-switchs
const VECTOR3 P12_TOGGLE_POS[P12_NSWITCH] = {
	{ 1.01020, 0.07249, 1.51678}, { 1.08673, 0.10035, 1.49908}, { 1.12601, 0.11465, 1.45174}, { 1.04277, 0.08435, 1.45174},
	{ 1.12601, 0.11465, 1.39949}, { 1.04277, 0.08435, 1.39949}, { 1.12734, 0.11513, 1.34949}, { 1.08975, 0.10145, 1.34949},
	{ 1.10855, 0.10829, 1.30949}, { 1.10855, 0.10829, 1.26949}, { 1.05714, 0.08958, 1.26396}, { 1.10855, 0.10829, 1.22949},
	{ 1.05714, 0.08958, 1.22396}, { 1.11352, 0.11010, 1.18210}, { 1.05714, 0.08958, 1.18927}, { 1.05714, 0.08958, 1.14927},
	{ 1.11352, 0.11010, 1.13210}, { 1.05714, 0.08958, 1.12073}, { 1.11352, 0.11010, 1.09210}, { 1.05714, 0.08958, 1.08073},
	{ 1.00075, 0.06906, 1.08073}, { 1.05714, 0.08958, 1.04375}
	};

// Panel 12 Dials
const VECTOR3 P12_DIAL_POS[P12_NDIAL] = { 
	{ 1.01313, 0.07094, 1.02660}, { 1.01313, 0.07094, 0.95302}, { 1.10485, 0.10432, 0.88523}, { 1.02386, 0.07484, 0.88523}
	};

// Panel 14 Toggle-switchs
const VECTOR3 P14_TOGGLE_POS[P14_NSWITCH] = { 
	{ 1.03621, 0.31420, 1.32009}, { 1.03621, 0.31420, 1.25009}, { 1.07247, 0.33111, 1.18009}, { 1.03621, 0.31420, 1.18009},
	{ 1.07247, 0.33111, 1.15009}, { 1.07247, 0.33111, 1.11326}, { 1.03621, 0.31420, 1.11326}, { 1.07247, 0.33111, 1.08326},
	{ 1.03621, 0.31420, 1.08326}, { 1.07247, 0.33111, 1.05326}, { 1.03621, 0.31420, 1.05326}, { 1.06281, 0.32661, 1.00857},
	{ 1.06281, 0.32661, 0.96491}, { 1.06281, 0.32661, 0.92641}, { 1.06281, 0.32661, 0.88962}, { 1.06281, 0.32661, 0.83221}
	};

// Panel 14 Dial
const VECTOR3 P14_DIAL_POS[P14_NDIAL] = {{ 1.08456, 0.33399, 1.25001}};

// ==============================================================
// Class declaration
// ==============================================================
class LM_COCKPIT 
{

That is a list of every switch, display, and button in our cockpit. each with a unique index number and 3D position assigned to it.

Yes it's a lot of information, but defining it once in the header file allows us to access it at will and will make what comes next a lot easier. Lets start with something simple, making the door open.

Open our RegisterActiveAreas function and add the following lines...

Code:
// --------------------------------------------------------------
// Register VC active areas
// --------------------------------------------------------------
void LM_COCKPIT::RegisterActiveAreas (VECTOR3 ofs)
{
	int i = 0;

[COLOR="Red"]	// EVA hatch handle
	oapiVCRegisterArea (AID_EVAHANDLE_OPEN, PANEL_REDRAW_NEVER, PANEL_MOUSE_DOWN);
	oapiVCSetAreaClickmode_Spherical( AID_EVAHANDLE_OPEN, _V(-0.3356, -0.6232, 1.5988) + ofs, 0.08);

	oapiVCRegisterArea (AID_EVAHANDLE_CLOSE, PANEL_REDRAW_NEVER, PANEL_MOUSE_DOWN);
	oapiVCSetAreaClickmode_Spherical (AID_EVAHANDLE_CLOSE, _V( 0.3300, -0.4888, 0.9368) + ofs, 0.08);[/COLOR]

What we are doing here is creating two active areas. thier postions correlate to the positions of the EVA hatch's door handle when the door is open and when the door is closed. Let's break them down.

"oapiVCRegisterArea (AID_EVAHANDLE_OPEN, PANEL_REDRAW_NEVER, PANEL_MOUSE_DOWN);
"

This line is the initial declaration of the active area. "AID_EVAHANDLE_OPEN" is the index number as defined in our header file, "PANEL_REDRAW_NEVER" indicates that there are no "redraw events" associated with the active area. Redraw events are how the VC updates things like gauges and other displays. "PANEL_MOUSE_DOWN" means that the active area is activated when someone clicks on it (mouse button is down).

"oapiVCSetAreaClickmode_Spherical (AID_EVAHANDLE_CLOSE, _V( 0.3300,-0.4888, 0.9368) + ofs, 0.08);"

This line states what kind of active area we are dealing with and it's posittion within the cockpit. In this case the active area is a spherical zone 0.08 units in diameter (8 cm) at the position indicated.

Now that we have an active area it's time to assign a function to it.

In the vessel class itself parsing of cockpit inputs is handled by "clbkVCMouseEvent" to serve this purpose you will see that I have placed a function called "MouseEvent" in our cockpit control class.

In it I have placed the following lines...

Code:
// --------------------------------------------------------------
// Respond to user inputs
// --------------------------------------------------------------
bool LM_COCKPIT::MouseEvent (int id, int event, VECTOR3 &p)
{
[COLOR="Red"]	switch (id) 
	{
	// EVA hatch handle
	case AID_EVAHANDLE_OPEN:
		if (v->HatchStatus == CLOSED) v->HatchStatus = OPENING; // If hatch is closed open hatch
		return true;

	case AID_EVAHANDLE_CLOSE:
		if (v->HatchStatus == OPEN) v->HatchStatus = CLOSING; // If hatch is open close hatch
		return true;
}[/COLOR]
return false;

When the user clicks on an active area Orbiter automatically passes the index number of the area to the mouse event parser, the "id" variable in the above code. The parser then compares that id number to it's list of possibles contained in the "switch (id)" function. If it finds a match it performs the assigned function and returns true, otherwise it returns false.

In this case the functions and their purpose should be readily apparent.

NOTE: v-> is a interface that allows us to manipulate data/call functions from our parent vessel as described in part 13.

Now that we have the some active areas registered and some lines for our parser to chew on we need to add them to our simulation. Our cockpit is not actually a vessel, planet, mfd, or somesuch and as such Orbiter will ignore it unless we specifically tell it otherwise.

To do this we need to go back to our lunar module's code and add calls for the cockpit's functions.

In ClbkLoadVC add a call to register our active areas.

Code:
// --------------------------------------------------------------
// Load virtual cockpit mode
// --------------------------------------------------------------
bool LM::clbkLoadVC (int id)
{
	// Check CG offset 
	VECTOR3 ofs;
	if (CoG_shifted) ofs = _V( 0, 0, 0);
	else ofs = LM_ASC_OFFSET; 

	// Register MFD
	static VCMFDSPEC Cmd_MFD = {mesh_Cockpit, VC_GRP_MFD_Cmd};		// Surface on which to display MFD. (Mesh, Mesh Group)
	oapiVCRegisterMFD (0, &Cmd_MFD);								// Register MFD in orbiter's interface [registry # and VCMFDSPEC]. (registry numbers start at 0 and count up)

[COLOR="red"]	// Register active areas
	vc->RegisterActiveAreas (ofs);
[/COLOR]

Then to handle our mouse events overload "clbkVCMouseEvent" and add the following line.

Code:
// --------------------------------------------------------------
// Respond to virtual cockpit mouse events
// --------------------------------------------------------------
bool LM::clbkVCMouseEvent (int id, int event, VECTOR3 &p)
{
[COLOR="red"]	return vc->MouseEvent (id, event, p); // Pass user inputs to cockpit control class[/COLOR]
} // End "LM::clbkLoadVC"

The active areas should now be registered in orbiter and user inputs will be passed to the cockpit control class to be parsed.

Compile and test your handy work. clicking on the hatch handle in the VC should now cause the hatch to open or close.

picture.php


NEXT UP: Animated Switches.
 

BruceJohnJennerLawso

Dread Lord of the Idiots
Addon Developer
Joined
Apr 14, 2012
Messages
2,585
Reaction score
0
Points
36
Looks good :)

It might help if you did it with a quadrilateral click area as well. I had issues getting that part to work when I first started with VC controls.
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
BruceJohnJennerLawso;bt5203 said:
Looks good :)

It might help if you did it with a quadrilateral click area as well. I had issues getting that part to work when I first started with VC controls.

I used a quadrilateral area for the MFD and Pilot's Keypad. They will be covered in a later post.
 
Top