Tutorial Coding a .dll Vessel for those who don't know how to code.

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
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 :censored: 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.

picture.php


Select windows 32bit project from the pop-up menu

picture.php


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...

picture.php


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

picture.php


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".

picture.php


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

picture.php


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)
picture.php


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.

picture.php


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.

picture.php


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.

picture.php


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

picture.php


...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:

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
Very good initiative ! :thumbup:

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

 

orb

O-F Administrator,
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
Don't add orbiter.lib and Orbitersdk.lib to Resource Files in Solution Explorer. :nono:

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:
    • 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.
    • 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:
    • Add in the Property Manager either "Orbitersdk/resources/Orbiter plugin.props" or "Orbitersdk/resources/Orbiter vessel.props" to either Debug or Release configuration.
    • When you completely expand previously added property sheet, there should be "orbiterroot" property sheet. Double click on it.
    • 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.
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
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.


  1. 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" :lol:

    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 ----------

    Very good initiative ! :thumbup:

    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.
 

orb

O-F Administrator,
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
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.

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.

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. :p


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.
 

Ripley

Tutorial translator
Donator
Joined
Sep 12, 2010
Messages
3,133
Reaction score
407
Points
123
Location
Rome
Website
www.tuttovola.org
...There's no way in hell I'm touching something labeled "expert settings"...
:lol:

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!!
:cheers:
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
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.
 

Mr Martian

Orbinaut/Addon dev/Donator
Addon Developer
Donator
Joined
Jun 6, 2012
Messages
288
Reaction score
67
Points
28
Location
Sydney, Australia, Earth, Sol
Website
www.orbithangar.com
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...:idk:
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
Next topic has been selected it seems.

Can't brain now, drunk but wil get on it
 

BruceJohnJennerLawso

Dread Lord of the Idiots
Addon Developer
Joined
Apr 14, 2012
Messages
2,585
Reaction score
0
Points
36
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...:idk:

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;)
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
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...:idk:

What do you need animated?
 

Mr Martian

Orbinaut/Addon dev/Donator
Addon Developer
Donator
Joined
Jun 6, 2012
Messages
288
Reaction score
67
Points
28
Location
Sydney, Australia, Earth, Sol
Website
www.orbithangar.com
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! :lol:

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

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 a moderator:

BruceJohnJennerLawso

Dread Lord of the Idiots
Addon Developer
Joined
Apr 14, 2012
Messages
2,585
Reaction score
0
Points
36
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! :lol:

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



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;
}

:blink: Hmm, looks like a couple of things are slightly odd. Why do you have #include for all of those pieces of DG code? Not that anyone would really object, but I dont think theres any way you could realistically integrate those into a beginners project. This is preference, I believe but the Vessel class definitions (class ShuttlePB: public VESSEL3 {... and so on) would be better placed in your Myvessel.h file, along with all of your numerical constants (double constant...). I cant say for sure whether they need to be in a header (.h) file to work, but Itll be much easier to organize the project if you do. To the best of my knowledge, (and I would apprec a correction here if im wrong) you must declare member functions of a vessel class in that code section I mentioned earlier

class ShuttlePB: public VESSEL3 {}

In between the curly brackets is where I believe you need to define "DefineAnimations", something like

class ShuttlePB: public VESSEL3 {
DefineAnimations();
}

(note double brackets and semicolon are very important at the end. C++ is freakier than most English teachers about punctuation in its code, although it usually makes more sense than them to me :lol:)

Then I think you need to move this

// 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);

into Define animations, which is empty right now (\\ before a line of code is called commenting it out, preventing it from being used by the compiler)

Important thing to watch when setting up anims (and a lot of other things too) is the clbkLoadStateEx, and clbkSaveState functions (which also need to be defined in your vessel class like DefineAnimations above). These represent how orbiter pulls parameters from those SCN files under the scenario directory. This is very important for the vessel, not only to save the state of an animation through the Scenario editor, but because Orbiter seems to generate a virtual version of the SCN file that it reads from every frame or timestep, and thus will crash if it cant find a requested parameter during a simulation.

Anyways, Im going to go try to create that sample animation snippet for you that should allow for at least one basic animation. Before using it, however youre going to need to do the cleanup on the project (I would even reccomend starting over with the MyVessel 2010 project you appear to be using), in order to get it to something vaguely useable
 

ionif

NASA
Addon Developer
Joined
May 15, 2010
Messages
230
Reaction score
3
Points
18
Location
Romania
Thanks for tutorial.Please who want to make tutorial for: How to makes animations for orbiter mesh.
 
Top