Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Space Flight Simulator > Tutorials & Challenges
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Tutorials & Challenges Feel free to publish your tutorials, challenges, & flight scenarios in this forum.

Reply
 
Thread Tools
  #1  
Old
Hlynkacg's Avatar
Hlynkacg Hlynkacg is offline
Aspiring rocket scientist


Default Coding a .dll Vessel for those who don't know how to code.
by Hlynkacg 08-22-2012, 03:42 AM

Hi there and Hail probe!

My name's Greg (aka Hlynkacg) and the title of this tutorial is "How to code a Vessel .dll when you don't know how to code".

I do not have any background in computers. I was an aviation rescue swimmer in the US Navy for 6 years and a paramedic for another two. In general I prefer problems that can be solved through the liberal application of a first-aid kit and/or violence.

That said I am also a life-long aviation/aerospace geek with a compulsive need to tinker, and am currently going to school on the GI bill to be an aerospace engineer

I don't know about c++ outside the bounds of Orbiter's API.

I'm writing this tutorial in the hopes that it will help other hobbiests, tinkerers, and budding addon developers avoid the stupid mistakes and general frustration I've subjected myself to.

With that out of the way, Let's Begin...

PART 1: Starting a project

To code a .dll you will first need a program capable of editing and compiling .cpp files.

Microsoft's Visual Studio is pretty much the gold standard in this regard and you can download the "Express" version for free here.

Go and install it if you haven't already. Assuming you also have orbiter installed, you now have everything you need to develope your very own .dll vessel.

Once you have Visual studio installed open it up and start a new project.



Select windows 32bit project from the pop-up menu



Now note that the default project is an application (.exe file) and we want to create a dynamic library (.dll file), click on application settings...



...and select the ".dll" and "empty project" check boxes.



You now have a blank canvas.

click on the "source files" folder in the left hand drop down menu and select "add a new file".



select c++ source code (.cpp file) and name it after your vessel.



From here if you were a hard core c++ ninja you'd just get to coding.

The fact that you've even read this far implies that you are not. Personally I always start by modifying an existing vessel. With this in mind, go to you orbiter directory and open the orbitersdk folder. Open samples\ShuttlePB\ShuttlePB.cpp and just copy/paste the whole thing into your project.

In theory you now have a entirely functional addon.

However if you try to compile (export to a .dll) you will get an error. (note the red squiggle)


This is because the file contains a whole bunch of instructions that Visual Studio doesn't know what to do with. Things like "SetThrusterResource(x, y)" and "SetDockParams(a,b,c)" that are unique to Orbiter.

There are two things we need to do to overcome this.



The first is to go into your project properties and tell Visual Studio to include the files that contain these instructions in it's searches. These files are contained within the convieniently named "include" folder found within orbiters sdk folder ^see screen-shot^

The second is to add the orbiter addon developement libraries to our project.

Click on "resources" folder in the left hand drop down menu and select "add an existing file". Select Orbiter.lib and orbitersdk.lib from the orbitersdk folder and add them to your project.

Your project should now compile sucessfully, Copy your shiny new vessel.dll into the modules folder of your orbiter installation.



You now have a .dll vessel but but there is one more step before you can fly it in Orbiter. You need a config file for it. Config files are simple text files that tell orbiter where to find various files and how to treat them. (Is it a moon or a space station?) config files for vessels are can be found in the config\vessels folder of your orbiter.

You can either copy an existing one and change the dll name or create your own. The format of these files is explained in 3Dmodels.pdf in the orbitersdk documentation.



You now have a vessel that looks and performs exacly like a ShuttlePB



...but not for long.

This tutorial is continued in Coding a Lunar Lander from the ground up

I also recommend reading the excellent how to turn a ShuttlePB into Surveyor.

Last edited by Hlynkacg; 02-27-2013 at 12:25 AM.
Reply With Quote
Views 11613 Comments 16
Total Comments 16

Comments

Old 08-22-2012, 05:38 AM   #2
liber
Orbinaut
 
liber's Avatar
Default

Thanks,going to try this when come back home.
liber is offline   Reply With Quote
Old 08-22-2012, 06:42 AM   #3
IronRain
Moderator
 
IronRain's Avatar


Default

Thanks, I'm going to follow this!
IronRain is offline   Reply With Quote
Old 08-22-2012, 07:07 AM   #4
N_Molson
Addon Developer
 
N_Molson's Avatar

Default

Very good initiative !

And again, that video is an absolute must-watch :

N_Molson is offline   Reply With Quote
Old 08-22-2012, 09:50 AM   #5
orb
O-F Administrator
Ninja
 
orb's Avatar

Default

Don't add orbiter.lib and Orbitersdk.lib to Resource Files in Solution Explorer.

There is much simpler way, which will save you much time for each project's configuration.

Two words: Property Sheets.
  1. Change "Tools->Settings" to "Expert Settings" to enable Property Manager.

  2. If you haven't converted any stock sample project yet:
    1. Edit Orbitersdk/resources/orbiterroot.vsprops in Visual Studio (it will open a text editor) or in a text editor of your choice and change OrbiterDir UserMacro's Value to the path where your Orbiter is located.
    2. Convert both a vessel sample and a plug-in sample to VS2010 format, by opening their solution files.

  3. If you have already converted some vessel sample and plug-in project to VS2010, but haven't changed the OrbiterDir macro:
    1. Add in the Property Manager either "Orbitersdk/resources/Orbiter plugin.props" or "Orbitersdk/resources/Orbiter vessel.props" to either Debug or Release configuration.
    2. When you completely expand previously added property sheet, there should be "orbiterroot" property sheet. Double click on it.
    3. Change "OrbiterDir" User Macro to point to your Orbiter root directory.

  4. Add "Orbitersdk/resources/Orbiter Debug.props" to the Debug configuration in Property Manager of your project, and appropriately "Orbitersdk/resources/Orbiter plugin.props" or "Orbitersdk/resources/Orbiter vessel.props" to both Release and Debug configuration.

  5. You're set. No need to change properties to add include paths, libraries, output directories or include libraries in the Solution Explorer (which is completely wrong, IMO).

From now on, all you need to do in your new projects is to add "Orbiter Debug.props" and "Orbiter vessel.props" or "Orbiter plugin.props" to Property Manager. All the required project parameters are set. Only when you need additional dependencies like OrbiterSound or UMMU libraries, you add them in the project properties.
orb is offline   Reply With Quote
Old 08-22-2012, 05:12 PM   #6
Hlynkacg
Aspiring rocket scientist
 
Hlynkacg's Avatar


Default

Quote:
Originally Posted by orb View Post
 
There is much simpler way, which will save you much time for each project's configuration.

Two words: Property Sheets.
[list=1][*]Change "Tools->Settings" to "Expert Settings" to enable Property Manager.
You forget that you're talking to somebody who knows jack squat about c++

There's no way in hell I'm touching something labeled "expert settings"

Quote:
You're set. No need to change properties to add include paths, libraries, output directories or include libraries in the Solution Explorer (which is completely wrong, IMO).
Why is it wrong?

---------- Post added at 05:12 PM ---------- Previous post was at 05:11 PM ----------

Quote:
Originally Posted by N_Molson View Post
 Very good initiative !

And again, that video is an absolute must-watch :

Orbiter : setting up the developpement environnment (by ComputerRex)
I actually hadn't seen that before.

Now I feel a bit silly.
Hlynkacg is offline   Reply With Quote
Old 08-22-2012, 05:41 PM   #7
orb
O-F Administrator
Ninja
 
orb's Avatar

Default

Quote:
Originally Posted by Hlynkacg View Post
 Why is it wrong?
Simply, Orbiter.lib and Orbitersdk.lib aren't part of your project, but additional dependencies, and as such they shouldn't be listed in the solution explorer as part of your project, but that's my opinion.

Normally you put libraries in linker's additional dependencies section of project properties, and Orbiter property sheets do it for you, as well as they set the include, library search, and output paths.

Quote:
Originally Posted by Hlynkacg View Post
 There's no way in hell I'm touching something labeled "expert settings"
It simply changes the user interface to more friendly and well known from earlier versions of the Visual Studio, which used it by default.

Visual Studio 2010 simply dumbed down the menus and made it the default setting. If you ever used VS2005 or VS2008 and now you are missing many useful functions in VS2010, the "Expert Settings" will bring those functions back.

Quote:
Originally Posted by Hlynkacg View Post
 You forget that you're talking to somebody who knows jack squat about c++
Nothing about C++ there; it only makes the IDE more powerful; C++ level doesn't change at all. You may know completely nothing about C++ and still find the "Expert Settings" useful.



Anyway, you don't need to use Orbiter property sheets, but they are already there, just waiting for you, so why not use them and save 5 minutes, you'd otherwise spend on project configuration, and by that time you could forget to set some of the parameters, which are all set for you in the property sheets.
orb is offline   Reply With Quote
Thanked by:
Old 08-22-2012, 05:58 PM   #8
Ripley
Tutorial translator
 
Ripley's Avatar
Default

Quote:
Originally Posted by Hlynkacg View Post
 ...There's no way in hell I'm touching something labeled "expert settings"...


I really like threads like this one, but I think making a C++ DLL for Orbiter (or for any product) definitely IS something for experts, or will eventually turn you into an expert, so why not touching such a label just at the start??
You're anyway lost, during this thread you'll become an expert anyway!!
Ripley is offline   Reply With Quote
Old 08-22-2012, 07:24 PM   #9
N_Molson
Addon Developer
 
N_Molson's Avatar

Default

Quote:
so why not touching such a label just at the start??
To avoid having people running away and limit themselves to the nice but antique spacecraft3/multistage2.

No, really, it isn't that hard.
N_Molson is offline   Reply With Quote
Old 08-26-2012, 05:20 AM   #10
Mr Martian
Orbinaut/Addon dev/Donator
 
Mr Martian's Avatar

Default

hey guys i am pretty new to orbiter and VERY new to coding. i am trying to code a space ship using the shuttlePB c++ file thingy and i have managed to change the trust directions and all that stuff but i cant seem to get animations working cos i have no idea how to add them!!! if anyone could help me out i would really appreciate it...
Mr Martian is offline   Reply With Quote
Old 08-26-2012, 05:50 AM   #11
Hlynkacg
Aspiring rocket scientist
 
Hlynkacg's Avatar


Default

Next topic has been selected it seems.

Can't brain now, drunk but wil get on it
Hlynkacg is offline   Reply With Quote
Old 08-26-2012, 06:44 AM   #12
Mr Martian
Orbinaut/Addon dev/Donator
 
Mr Martian's Avatar

Default

kthanks
Mr Martian is offline   Reply With Quote
Old 08-26-2012, 05:25 PM   #13
BruceJohnJennerLawso
Dread Lord of the Idiots
 
BruceJohnJennerLawso's Avatar
Default

Quote:
Originally Posted by Mr Martian View Post
 hey guys i am pretty new to orbiter and VERY new to coding. i am trying to code a space ship using the shuttlePB c++ file thingy and i have managed to change the trust directions and all that stuff but i cant seem to get animations working cos i have no idea how to add them!!! if anyone could help me out i would really appreciate it...
If you post your code here, Ill add the animation code youre going to need for you. I dont think I have time to develop it to work with whatever you need for the model, but if you check the API guide, you should be able to figure it out
BruceJohnJennerLawso is offline   Reply With Quote
Old 08-26-2012, 06:13 PM   #14
gattispilot
Addon Developer
 
gattispilot's Avatar
Default

Quote:
Originally Posted by Mr Martian View Post
 hey guys i am pretty new to orbiter and VERY new to coding. i am trying to code a space ship using the shuttlePB c++ file thingy and i have managed to change the trust directions and all that stuff but i cant seem to get animations working cos i have no idea how to add them!!! if anyone could help me out i would really appreciate it...
What do you need animated?
gattispilot is offline   Reply With Quote
Old 08-27-2012, 01:37 AM   #15
Mr Martian
Orbinaut/Addon dev/Donator
 
Mr Martian's Avatar

Default

ok its kinda complicated, i made this mesh and ive been using vinka's spacecraft 3.dll thing but i want to get into coding cos i can have multiple instances and smoke that comes out of the hover engines and all that stuff u get with a vessel module, so i used the vc++ tool and used the ShuttlePB which doesnt have any gear or doors or any animations... anyway i got the .dll compiled and it works and the thrusters are in the right places and all that so its working and all, but i cant seem to define animations, i have no idea how and i cant use the animation sequences that the shuttle PB uses cos it doesnt have any! i dont want to do anything complicated i just want to make a door open and (a simple translation) and a couple of rotations thats all but i have no idea how to correctly define the animations it comes up with an error and says that "ShuttlePB has no member: "DefineAnimations" its really frustrating cos all i need is those animations and im done!!! so if u know a simple way to get it working that would be epic!

---------- Post added at 01:37 AM ---------- Previous post was at 01:35 AM ----------

Quote:
Originally Posted by BruceJohnJennerLawso View Post
 If you post your code here, Ill add the animation code youre going to need for you. I dont think I have time to develop it to work with whatever you need for the model, but if you check the API guide, you should be able to figure it out
kthanks i have the entire vessel code here:

Code:
// ==============================================================
//                 ORBITER MODULE: ShuttlePB
//                  Part of the ORBITER SDK
//          Copyright (C) 2002-2004 Martin Schweiger
//                   All rights reserved
//
// ShuttlePB.cpp
// Control module for ShuttlePB 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 "MyVessel.h"
#include "DeltaGlider.h"
#include "AAP.h"
#include "MFDButton.h"
#include "Horizon.h"
#include "InstrHsi.h"
#include "InstrAoa.h"
#include "InstrVs.h"
#include "RcsDial.h"
#include "AtctrlDial.h"
#include "NavButton.h"
#include "ElevTrim.h"
#include "Airbrake.h"
#include "UndockBtn.h"
#include "HudBtn.h"
#include "GearLever.h"
#include "NconeLever.h"
#include "FuelMfd.h"
#include "ThrottleMain.h"
#include "ThrottleHover.h"
#include "ThrottleScram.h"
#include "GimbalCtrl.h"
#include "SwitchArray.h"
#include "AirlockSwitch.h"
#include "Wheelbrake.h"
#include "MwsButton.h"
#include "ScnEditorAPI.h"
#include "DlgCtrl.h"
#include "meshres.h"
#include <stdio.h>
#include <math.h>

//=========================================================
// Vessel Animations
//=========================================================
void MyVessel::DefineAnimations()
{
	//ANIMATIONCOMPONENT_HANDLE parent;
	//static UINT gear_groups[2] = {5,6};
	//static MGROUP_ROTATE gear (
	//	0,
	//	gear_groups,
	//	2,
	//	_V(0,-1.0,8.5),
	//	_V(1,0,0),
	//	(float)(0.45*PI)
	//);
	//static UINT wheel_groups[2] = {10,11};
	//wheel = new MGROUP_ROTATE (
	//	0,
	//	wheel_groups,
	//	2,
	//	_V(0,-1.0,6.5),
	//	_V(1,0,0),
	//	(float)(2*PI)
	//);
	//anim_gear = CreateAnimation (0.0);
	//parent = AddAnimationComponent (anim_gear, 0, 1, &gear);
	//anim_wheel = CreateAnimation (0.0);
	//AddAnimationComponent (anim_wheel, 0, 1, wheel, parent);
}

//=========================================================
// Vessel Capabilities
//=========================================================
void MyVessel::clbkSetClassCaps (FILEHANDLE cfg)
{
	// vessel caps definitions
}

//=========================================================
// Vessel Load and Save Parameters
//=========================================================
void MyVessel::clbkLoadStateEx (FILEHANDLE scn, void *status)
{
	char *line; while (oapiReadScenario_nextline (scn, line))
	{
		if (!strnicmp (line, "MYPARAM", 7))
		{
			sscanf (line+7, "%lf", &myparam);
		}
		else
		{
			ParseScenarioLineEx (line, status);
		}
	}
}

void MyVessel::clbkSaveState (FILEHANDLE scn)
{
	VESSEL3::clbkSaveState (scn);
	oapiWriteScenario_float (scn, "MYPARAM", myparam);
}

//=========================================================
// Animation Template
//=========================================================
void MyVessel::Timestep (double simt)
{
	//if (gear_status == CLOSING || gear_status == OPENING)
	//{
	//	double da = oapiGetSimStep() * gear_speed;
	//	if (gear_status == CLOSING)
	//	{
	//		if (gear_proc > 0.0)
	//			gear_proc = max (0.0, gear_proc-da);
	//		else
	//			gear_status = CLOSED;
	//	}
	//	else
	//	{
	//		// door opening
	//		if (gear_proc < 1.0)
	//			gear_proc = min (1.0, gear_proc+da);
	//		else
	//			gear_status = OPEN;
	//	}
	//	SetAnimation (anim_gear, gear_proc);
	//}
}

//=========================================================
// Load and Delete Module Stuff
//=========================================================
DLLCLBK void InitModule (HINSTANCE hModule)
{
	// perform global module initialisation here
}
DLLCLBK void ExitModule (HINSTANCE hModule)
{
	// perform module cleanup here
}

//=========================================================
// Load and Delete Vessel Stuff
//=========================================================
DLLCLBK VESSEL *Init (OBJHANDLE hvessel, int flightmodel)
{
	return new MyVessel (hvessel, flightmodel);
}
DLLCLBK void Exit (VESSEL *vessel)
{
	if (vessel)
		delete (MyVessel*)vessel;
}

// ==============================================================
// Some vessel parameters
// ==============================================================
const double  PB_SIZE       = 322.5;             // mean radius [m]
const VECTOR3 PB_CS         = {10.5,15.0,5.8}; // x,y,z cross sections [m^2]
const VECTOR3 PB_PMI        = {2.28,2.31,0.79};// principal moments of inertia (mass-normalised) [m^2]
const VECTOR3 PB_RD         = {0.025,0.025,0.02};//{0.05,0.1,0.05};  // rotation drag coefficients
const double  PB_EMPTYMASS  = 150000000.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,-1.5,2},{-1,-1.5,-1.5},{1,-1.5,-1.5}}; // touchdown points [m]
const VECTOR3 PB_COP        = {0,0,0};//{0,0,-0.1};      // centre of pressure for airfoils [m]
const double  PB_VLIFT_C    = 2.0;             // chord length [m]
const double  PB_VLIFT_S    = 2.0;             // wing area [m^2]
const double  PB_VLIFT_A    = 2.5;             // wing aspect ratio
const double  PB_HLIFT_C    = 2.0;             // chord length [m]
const double  PB_HLIFT_S    = 1.5;             // wing area [m^2]
const double  PB_HLIFT_A    = 2.0;             // wing aspect ratio

const double  PB_MAXMAINTH  = 1.047e10;
const double  PB_MAXRETROTH  = 1.047e10;
const double  PB_MAXHOVERTH = 3.0e9;
const double  PB_MAXRCSTH   = 6.3e5;

const VECTOR3 PB_DOCK_POS   = {0,1.3,-1};      // docking port location [m]
const VECTOR3 PB_DOCK_DIR   = {0,1,0};         // docking port approach direction
const VECTOR3 PB_DOCK_ROT   = {0,0,-1};        // docking port alignment direction

// Calculate lift coefficient [Cl] as a function of aoa (angle of attack) over -Pi ... Pi
// Implemented here as a piecewise linear function
double LiftCoeff (double aoa)
{
	int i;
	const int nlift = 9;
	static const double AOA[nlift] = {-180*RAD,-60*RAD,-30*RAD,-1*RAD,15*RAD,20*RAD,25*RAD,60*RAD,180*RAD};
	static const double CL[nlift]  = {       0,      0,   -0.1,     0,   0.2,  0.25,   0.2,     0,      0};
	static const double SCL[nlift] = {(CL[1]-CL[0])/(AOA[1]-AOA[0]), (CL[2]-CL[1])/(AOA[2]-AOA[1]),
		                              (CL[3]-CL[2])/(AOA[3]-AOA[2]), (CL[4]-CL[3])/(AOA[4]-AOA[3]),
									  (CL[5]-CL[4])/(AOA[5]-AOA[4]), (CL[6]-CL[5])/(AOA[6]-AOA[5]),
									  (CL[7]-CL[6])/(AOA[7]-AOA[6]), (CL[8]-CL[7])/(AOA[8]-AOA[7])};
	for (i = 0; i < nlift-1 && AOA[i+1] < aoa; i++);
	return CL[i] + (aoa-AOA[i])*SCL[i];
}

// ==============================================================
// Shuttle-PB class interface
// ==============================================================

class ShuttlePB: public VESSEL3 {
public:
	ShuttlePB (OBJHANDLE hVessel, int flightmodel);
	~ShuttlePB ();
	void clbkSetClassCaps (FILEHANDLE cfg);

private:
	static void vlift (VESSEL *v, double aoa, double M, double Re,
		void *context, double *cl, double *cm, double *cd);
	static void hlift (VESSEL *v, double aoa, double M, double Re,
		void *context, double *cl, double *cm, double *cd);

	// transformations for control surface animations
	static MGROUP_ROTATE trans_Laileron, trans_Raileron;
	static MGROUP_ROTATE trans_Lelevator, trans_Relevator;
};

ShuttlePB::ShuttlePB (OBJHANDLE hVessel, int flightmodel)
: VESSEL3 (hVessel, flightmodel)
{
}

ShuttlePB::~ShuttlePB ()
{
}

// animation transformation definitions
static UINT GRP_LWING = 2;
static UINT GRP_RWING = 3;
static VECTOR3 LWING_REF  = {-1.3,-0.725,-1.5};
static VECTOR3 LWING_AXIS = {-0.9619,-0.2735,0};
static VECTOR3 RWING_REF  = {1.3,-0.725,-1.5};
static VECTOR3 RWING_AXIS = {0.9619,-0.2735,0};
static float AILERON_RANGE = (float)(20.0*RAD);
static float ELEVATOR_RANGE = (float)(30.0*RAD);
MGROUP_ROTATE ShuttlePB::trans_Laileron (0, &GRP_LWING, 1, LWING_REF, LWING_AXIS, AILERON_RANGE);
MGROUP_ROTATE ShuttlePB::trans_Raileron (0, &GRP_RWING, 1, RWING_REF, RWING_AXIS, AILERON_RANGE);
MGROUP_ROTATE ShuttlePB::trans_Lelevator (0, &GRP_LWING, 1, LWING_REF, LWING_AXIS, -ELEVATOR_RANGE);
MGROUP_ROTATE ShuttlePB::trans_Relevator (0, &GRP_RWING, 1, RWING_REF, RWING_AXIS, ELEVATOR_RANGE);


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

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void ShuttlePB::clbkSetClassCaps (FILEHANDLE cfg)
{
	THRUSTER_HANDLE th_main, th_retro, th_hover, th_rcs[14], th_group[4];

	// physical vessel parameters
	SetSize (PB_SIZE);
	SetEmptyMass (PB_EMPTYMASS);
	SetPMI (PB_PMI);
	SetCrossSections (PB_CS);
	SetRotDrag (PB_RD);
	SetTouchdownPoints (PB_TDP[0], PB_TDP[1], PB_TDP[2]);

	// docking port definitions
	SetDockParams (PB_DOCK_POS, PB_DOCK_DIR, PB_DOCK_ROT);

	// airfoil definitions
	CreateAirfoil3 (LIFT_VERTICAL,   PB_COP, vlift, NULL, PB_VLIFT_C, PB_VLIFT_S, PB_VLIFT_A);
	CreateAirfoil3 (LIFT_HORIZONTAL, PB_COP, hlift, NULL, PB_HLIFT_C, PB_HLIFT_S, PB_HLIFT_A);

	// control surface animations
	UINT anim_Laileron = CreateAnimation (0.5);
	UINT anim_Raileron = CreateAnimation (0.5);
	UINT anim_elevator = CreateAnimation (0.5);
	AddAnimationComponent (anim_Laileron, 0, 1, &trans_Laileron);
	AddAnimationComponent (anim_Raileron, 0, 1, &trans_Raileron);
	AddAnimationComponent (anim_elevator, 0, 1, &trans_Lelevator);
	AddAnimationComponent (anim_elevator, 0, 1, &trans_Relevator);

	// aerodynamic control surface defintions
	CreateControlSurface (AIRCTRL_ELEVATOR, 1.5, 0.7, _V( 0,0,-2.5), AIRCTRL_AXIS_XPOS, anim_elevator);
	CreateControlSurface (AIRCTRL_AILERON, 1.5, 0.25, _V( 1,0,-2.5), AIRCTRL_AXIS_XPOS, anim_Laileron);
	CreateControlSurface (AIRCTRL_AILERON, 1.5, 0.25, _V(-1,0,-2.5), AIRCTRL_AXIS_XNEG, anim_Raileron);

	// 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);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 8, 1, _V(0,0.3,-4.35), _V(0,0,-1));

	PARTICLESTREAMSPEC contrail_main = {
		0, 15.0, 46, 200, 0.15, 1.0, 5, 38.0, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e9, 1
	};
	PARTICLESTREAMSPEC exhaust_main = {
		0, 7.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,43,-384.7), &contrail_main);
	AddExhaustStream (th_main, _V(0,43,-384.7), &exhaust_main);
	AddExhaustStream (th_main, _V(0,-18,-384.7), &contrail_main);
	AddExhaustStream (th_main, _V(0,-18,-384.7), &exhaust_main);

	// retro engine
	th_retro = CreateThruster (_V(0,0,-4.35), _V(0,0,-1), PB_MAXMAINTH, hpr, PB_ISP);
	CreateThrusterGroup (&th_retro, 1, THGROUP_RETRO);
	AddExhaust (th_retro, 8, 1, _V(0,0.3,-4.35), _V(0,0,-1));

	PARTICLESTREAMSPEC contrail_retro = {
		0, 12.0, 16, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
	};
	PARTICLESTREAMSPEC exhaust_retro = {
		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_retro, _V(-27.5,16.40206,353.5885), &contrail_main);
	AddExhaustStream (th_retro, _V(-27.5,16.40206,353.5885), &exhaust_main);
	AddExhaustStream (th_retro, _V(27.5,16.40206,353.5885), &contrail_main);
	AddExhaustStream (th_retro, _V(27.5,16.40206,353.5885), &exhaust_main);

	// hover engine
	th_hover = CreateThruster (_V(0,-1.5,0), _V(0,1,0), PB_MAXHOVERTH, hpr, PB_ISP);
	CreateThrusterGroup (&th_hover, 1, THGROUP_HOVER);
	AddExhaust (th_hover, 30, 2.1, _V(-49.96603,6.653036,276.5305), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(49.96603,6.653036,276.5305), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(49.96603,6.653036,258.0454), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(-49.96603,6.653036,258.0454), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(-100.2151,6.653036,5.876923), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(-76.65325,6.653036,6.04678), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(100.2151,6.653036,5.876923), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(76.65325,6.653036,6.04678), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(48.3807,-24,-229.6315), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(48.39203,-24,-211.1653), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(-48.3807,-24,-229.6315), _V(0,-1,0));
	AddExhaust (th_hover, 30, 2.1, _V(-48.39203,-24,-211.1653), _V(0,-1,0));

	PARTICLESTREAMSPEC contrail_hover = {
		0, 5.0, 8, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 20,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
	};
	PARTICLESTREAMSPEC exhaust_hover = {
		0, 2.0, 10, 200, 0.05, 0.05, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
	};

	AddExhaustStream (th_hover, _V(-49.96603,6.653036,276.5305), &contrail_hover);
	AddExhaustStream (th_hover, _V(49.96603,6.653036,276.5305), &contrail_hover);
	AddExhaustStream (th_hover, _V(-49.96603,6.653036,276.5305), &exhaust_hover);
	AddExhaustStream (th_hover, _V(49.96603,6.653036,276.5305), &exhaust_hover);
	AddExhaustStream (th_hover, _V(-49.96603,6.653036,258.0454), &contrail_hover);
	AddExhaustStream (th_hover, _V(49.96603,6.653036,276.5305), &contrail_hover);
	AddExhaustStream (th_hover, _V(49.96603,6.653036,258.0454), &exhaust_hover);
	AddExhaustStream (th_hover, _V(-49.96603,6.653036,258.0454), &exhaust_hover);
	AddExhaustStream (th_hover, _V(-100.2151,6.653036,5.876923), &contrail_hover);
	AddExhaustStream (th_hover, _V(76.65325,6.653036,6.04678), &contrail_hover);
	AddExhaustStream (th_hover, _V(-76.65325,6.653036,6.04678), &exhaust_hover);
	AddExhaustStream (th_hover, _V(100.2151,6.653036,5.876923), &exhaust_hover);
	AddExhaustStream (th_hover, _V(100.2151,6.653036,5.876923), &contrail_hover);
	AddExhaustStream (th_hover, _V(-76.65325,6.653036,6.04678), &contrail_hover);
	AddExhaustStream (th_hover, _V(76.65325,6.653036,6.04678), &exhaust_hover);
	AddExhaustStream (th_hover, _V(-100.2151,6.653036,5.876923), &exhaust_hover);
	AddExhaustStream (th_hover, _V(48.3807,-24,-229.6315), &contrail_hover);
	AddExhaustStream (th_hover, _V(-48.3807,-24,-229.6315), &contrail_hover);
	AddExhaustStream (th_hover, _V(48.3807,-24,-229.6315), &exhaust_hover);
	AddExhaustStream (th_hover, _V(-48.3807,-24,-229.6315), &exhaust_hover);
	AddExhaustStream (th_hover, _V(48.39203,-24,-211.1653), &contrail_hover);
	AddExhaustStream (th_hover, _V(-48.39203,-24,-211.1653), &contrail_hover);
	AddExhaustStream (th_hover, _V(48.39203,-24,-211.1653), &exhaust_hover);
	AddExhaustStream (th_hover, _V(-48.39203,-24,-211.1653), &exhaust_hover);

	// RCS engines
	th_rcs[ 0] = CreateThruster (_V( 1,0, 3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 1] = CreateThruster (_V( 1,0, 3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 2] = CreateThruster (_V(-1,0, 3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 3] = CreateThruster (_V(-1,0, 3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 4] = CreateThruster (_V( 1,0,-3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 5] = CreateThruster (_V( 1,0,-3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 6] = CreateThruster (_V(-1,0,-3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 7] = CreateThruster (_V(-1,0,-3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 8] = CreateThruster (_V( 1,0, 3), _V(-1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 9] = CreateThruster (_V(-1,0, 3), _V( 1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[10] = CreateThruster (_V( 1,0,-3), _V(-1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[11] = CreateThruster (_V(-1,0,-3), _V( 1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[12] = CreateThruster (_V( 0,0,-3), _V(0,0, 1), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[13] = CreateThruster (_V( 0,0, 3), _V(0,0,-1), PB_MAXRCSTH, hpr, PB_ISP);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[2];
	th_group[2] = th_rcs[5];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[3];
	th_group[2] = th_rcs[4];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);

	CreateThrusterGroup (th_rcs+12, 1, THGROUP_ATT_FORWARD);
	CreateThrusterGroup (th_rcs+13, 1, THGROUP_ATT_BACK);

	// camera parameters
	SetCameraOffset (_V(0,1.478645,379.1345));

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

// ==============================================================
// Airfoil lift/drag functions
// ==============================================================

void ShuttlePB::vlift (VESSEL *v, double aoa, double M, double Re,
	void *context, double *cl, double *cm, double *cd)
{
	static const double clp[] = {  // lift coefficient from -pi to pi in 10deg steps
		-0.1,-0.5,-0.4,-0.1,0,0,0,0,0,0,0,0,0,0,-0.2,-0.6,-0.6,-0.4,0.2,0.5,0.9,0.8,0.2,0,0,0,0,0,0,0,0,0,0.1,0.4,0.5,0.3,-0.1,-0.5
	};
	static const double aoa_step = 10.0*RAD;
	double a, fidx, saoa = sin(aoa);
	a = modf((aoa+PI)/aoa_step, &fidx);
	int idx = (int)(fidx+0.5);
	*cl = clp[idx]*(1.0-a) + clp[idx+1]*a;     // linear interpolation
	*cm = 0.0; //-0.03*sin(aoa-0.1);
	*cd = 0.03 + 0.4*saoa*saoa;                // profile drag
	*cd += oapiGetInducedDrag (*cl, 1.0, 0.5); // induced drag
	*cd += oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04);  // wave drag
}

void ShuttlePB::hlift (VESSEL *v, double aoa, double M, double Re,
	void *context, double *cl, double *cm, double *cd)
{
	static const double clp[] = {  // lift coefficient from -pi to pi in 45deg steps
		0,0.4,0,-0.4,0,0.4,0,-0.4,0,0.4
	};
	static const double aoa_step = 45.0*RAD;
	double a, fidx;
	a = modf((aoa+PI)/aoa_step, &fidx);
	int idx = (int)(fidx+0.5);
	*cl = clp[idx]*(1.0-a) + clp[idx+1]*a;     // linear interpolation
	*cm = 0.0;
	*cd = 0.03;
	*cd += oapiGetInducedDrag (*cl, 1.5, 0.6); // induced drag
	*cd += oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04);  // wave drag
}

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

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	return new ShuttlePB (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (ShuttlePB*)vessel;
}

Last edited by orb; 08-27-2012 at 09:22 AM. Reason: Use [code][/code] tags when you post code!
Mr Martian is offline   Reply With Quote
Reply

  Orbiter-Forum > Orbiter Space Flight Simulator > Tutorials & Challenges


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 03:35 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.