tauruslittrow84
New member
- Joined
- Nov 12, 2011
- Messages
- 58
- Reaction score
- 0
- Points
- 0
Hlynkac posted code to override Orbiters default autopilot to function with a tailsitter +Y oriented craft instead of Orbiter default +Z. In his post he apologized for not adding that 'RotateVector' comes from an unspecified special orbitermath.h file....In that post it is never revealed as to how you incorporate this bit of code
I am getting the following error because of it:
I need to know how to make "RotateVector" a member of my class. Do I copy this code into notepad and call it orbitermath.h and then include it. Tried that. Or do I just insert this math function directly into my .cpp? Kinda tried that too...Or is their some Apollo .h file I need to just include or maybe list in Project Linker dependencies???? Here is my current .h and .cpp files
updated to correct the earlier problems but I am still getting the error.
.h file
.cpp file
Code:
Rotate inputed coordinates around an arbitrary axis
// --------------------------------------------------------------
VECTOR3 RotateVector (const VECTOR3 &input, double angle, const VECTOR3 &rotationaxis)
{
// To rotate a vector in 3D space we'll need to build a matrix, these are the variables required to do so.
// NOTE: this version of the function takes it's input angle in Radians
double c = cos(angle);
double s = sin(angle);
double t = 1.0 - c;
double x = rotationaxis.x;
double y = rotationaxis.y;
double z = rotationaxis.z;
// Build rotation matrix
MATRIX3 rMatrix;
rMatrix.m11 = (t * x * x + c);
rMatrix.m12 = (t * x * y - s * z);
rMatrix.m13 = (t * x * z + s * y);
rMatrix.m21 = (t * x * y + s * z);
rMatrix.m22 = (t * y * y + c);
rMatrix.m23 = (t * y * z - s * x);
rMatrix.m31 = (t * x * z - s * y);
rMatrix.m32 = (t * y * z + s * x);
rMatrix.m33 = (t * z * z + c);
// Perform Rotation
VECTOR3 output = mul (rMatrix, input); // multiply the input vector by our rotation matrix to get our output vector
return output; // Return rotated vector
} // End "RotateVector"
I am getting the following error because of it:
Code:
c:\users\crice\documents\visual studio 2008\projects\chippersat\chippersat\chippersat.cpp(506) : error C2664: 'chippersat::RotateVector' : cannot convert parameter 2 from 'VECTOR3' to 'double'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I need to know how to make "RotateVector" a member of my class. Do I copy this code into notepad and call it orbitermath.h and then include it. Tried that. Or do I just insert this math function directly into my .cpp? Kinda tried that too...Or is their some Apollo .h file I need to just include or maybe list in Project Linker dependencies???? Here is my current .h and .cpp files
updated to correct the earlier problems but I am still getting the error.
.h file
Code:
#ifndef __chippersat_H
#define __chippersat_H
#include "orbitersdk.h"
#include "payloadmanager.h"
#define SOLARPANELSOUND 56
#define RADARFLAGSOUND 57
// ==============================================================
// Some parameters and capabilities
// ==============================================================
const double SOLARPANEL_OPERATING_SPEED = 0.025;
const double RADARFLAG_OPERATING_SPEED = 1.500;
// ==============================================================
// chippersat class interface
// ==============================================================
class chippersat: public VesselWithPM<chippersat> {
public:
enum DoorStatus { DOOR_CLOSED, DOOR_OPEN, DOOR_CLOSING, DOOR_OPENING } pan_status, radarflag_status;
enum Autopilots{ Off, Killrot, HLevel, Prograde, Retrograde, Normal, Antinormal, Hover};
chippersat (OBJHANDLE hObj, int fmodel);
BEACONLIGHTSPEC beacon[3];
MESHHANDLE vcmesh_tpl;
Autopilots AUTOPILOT; // Control mode
void DefineAnimations (void);
void ActivateSolarPanels (DoorStatus action);
void RevertSolarPanels (void);
void ActivateRadarflag (DoorStatus action);
void RevertRadarflag (void);
void OrientForBurn(VECTOR3& tgtVector);
void RotateVector (const VECTOR3 &input, double angle, const VECTOR3 &rotationaxis);
// Overloaded callback functions
void clbkSetClassCaps (FILEHANDLE cfg);
void clbkLoadStateEx (FILEHANDLE scn, void *vs);
void clbkSaveState (FILEHANDLE scn);
void clbkPreStep (double simt, double simdt, double mjd);
void clbkPostStep (double simt, double simdt, double mjd);
void chippersat::clbkPostCreation ();
int clbkConsumeBufferedKey (DWORD key, bool down, char *kstate);
int clbkGeneric (int msgid, int prm, void *context);
void PM_clbkPayloadJettisoned (int slot_idx, OBJHANDLE jettisoned_ship);
void PM_clbkVehicleCapsChanged();
int MyID;
bool shouldAnimateTheThing;
bool clbkLoadVC (int id);
void SetDockingLight (bool on);
int lightfront_status;
SpotLight *docking_lightfront;
private:
void DefineThrusters();
void Test();
UINT anim_pan, anim_radarflag, anim_panRtop;
char j_name[32];
double j_timer;
double pan_proc, radarflag_proc;
// script interface-related methods, implemented in HST_Lua.cpp
int Lua_InitInterpreter (void *context);
int Lua_InitInstance (void *context);
};
#endif // !__chippersat_H
.cpp file
Code:
#define ORBITER_MODULE
#include "chippersat.h"
#include "Orbitersdk.h"
#include "payloadmanager.h"
#include "ScnEditorAPI.h"
#include "DlgCtrl.h"
#include <math.h>
#include <stdio.h>
#include "OrbiterSoundSDK40.h"
#include "OrbiterAPI.h"
#include "DrawAPI.h"
// ==============================================================
// chippersat class implementation
// ==============================================================
// --------------------------------------------------------------
// Constructor
// --------------------------------------------------------------
chippersat::chippersat (OBJHANDLE hObj, int fmodel)
: VesselWithPM (hObj, fmodel)
{
shouldAnimateTheThing = false;
pan_proc = 0.0;
pan_status = DOOR_CLOSED;
radarflag_proc = 0.0;
DefineAnimations ();
j_name[0] = '\0';
j_timer = 0;
}
void chippersat::PM_clbkPayloadJettisoned(int slot_idx, OBJHANDLE jettisoned_ship)
{
oapiGetObjectName(jettisoned_ship, j_name, 32);
j_timer = -5;
}
void chippersat::PM_clbkVehicleCapsChanged()
{
//Here you can make some action on vehicle's capabilities change
}
//
// --------------------------------------------------------------
// Define animation sequences for moving parts
// --------------------------------------------------------------
void chippersat::DefineAnimations (void)
{
// 1. SolarPanels
ANIMATIONCOMPONENT_HANDLE parent1,parent2;
static UINT mgroup_pan1arm[1] = {4}; //PANEL with arm
static MGROUP_ROTATE pan1arm (0, mgroup_pan1arm, 1,
_V(1.987,1.780, 0.218 ), _V(0,-1,0), (float)(88*RAD));
static UINT mgroup_pan2arm[1] = {6}; //PANEL with arm
static MGROUP_ROTATE pan2arm (0, mgroup_pan2arm, 1,
_V(-2.172,1.780,0.035), _V(0,-1,0), (float)(95*RAD));
static UINT mgroup_pan3top[1] = {5}; //PANEL
static MGROUP_ROTATE pan3top (0, mgroup_pan3top, 1,
_V(2.045,1.940,1.882), _V(0, 0, 1), (float)(165*RAD));
static UINT mgroup_pan4top[1] = {7}; //PANEL
static MGROUP_ROTATE pan4top (0, mgroup_pan4top, 1,
_V(-2.125,1.940,.502 ), _V(0, 0, 1), (float)(-195*RAD));
static UINT mgroup_panRtop[1] = {7}; //PANEL
static MGROUP_ROTATE panRtop (0, mgroup_panRtop, 1,
_V(-2.093,1.940,1.414 ), _V(0, 1, 0), (float)(-8*RAD));
anim_pan = CreateAnimation (0.0);
parent1 = AddAnimationComponent (anim_pan, 0, .4, &pan1arm);
parent2 = AddAnimationComponent (anim_pan, 0, .4, &pan2arm);
AddAnimationComponent (anim_pan, .35, 1, &pan3top, parent1);
AddAnimationComponent (anim_pan, .35, 1, &pan4top, parent2);
anim_panRtop = CreateAnimation (0.0);
AddAnimationComponent (anim_pan, 0,.4, &panRtop);
// 2. Radar Flag
static UINT meshgroup_radarflag[1] = {8};
static MGROUP_ROTATE radarflag (0, meshgroup_radarflag, 1, _V(0.148,3.062,0.166), _V(0,1,0), (float)(360*RAD));
anim_radarflag = CreateAnimation (0);
AddAnimationComponent (anim_radarflag, 0, 1, &radarflag);
}
void chippersat::ActivateSolarPanels (DoorStatus action)
{
pan_status = action;
}
void chippersat::RevertSolarPanels (void)
{
ActivateSolarPanels ((pan_status == DOOR_CLOSED || pan_status == DOOR_CLOSING) ?
DOOR_OPENING : DOOR_CLOSING);
}
void chippersat::ActivateRadarflag (DoorStatus action)
{
radarflag_status = action;
}
// Orientation Autopilot
void chippersat::OrientForBurn(VECTOR3& tgtVector)
{
int i;
for (i = 1; i <= 7; i++) DeactivateNavmode(i); // To prevent competing inputs deactivate Orbiter's default autopilots.
if (oapiGetTimeAcceleration()> 10) oapiSetTimeAcceleration(1); // To prevent the autopilot from wasting fuel I've restricted time-accel to 10x or less.
normalise (tgtVector); // The target vector should already been normalised but I'll do it again just to be safe. Normalizing saves us from having to do a lot of math further down the line.
VECTOR3 ThrustVector = {0,1,0}; // chippersat::GetThrusterDir(th_descent, ThrustVector) // Get the direction of thrust for the main engine.
VECTOR3 input = crossp(tgtVector,ThrustVector);
VECTOR3 aVel; chippersat::GetAngularVel(aVel); // Get vessel's current angular velocity and break it down into...
double PitchV = aVel.x*DEG; // Pitch [degrees/sec]
double RollV = aVel.z*DEG; // Roll [degrees/sec]
double YawV = aVel.y*DEG; // Yaw [degrees/sec]
// Pitch Inputs
double CurrentRate = PitchV;
double CommandedRate = asin(input.x)*DEG;
double pDelta = (CommandedRate - CurrentRate);
if ( (pDelta > 0.00) && (CurrentRate <= 5.00) ) chippersat::IncThrusterGroupLevel_SingleStep(THGROUP_ATT_PITCHUP, pDelta);
else if ( (pDelta < 0.00) && (CurrentRate >= -5.00) ) chippersat::IncThrusterGroupLevel_SingleStep(THGROUP_ATT_PITCHDOWN, -pDelta);
// Roll Inputs
CurrentRate = RollV;
CommandedRate = asin(input.z)*DEG;
double rDelta = (CommandedRate - CurrentRate);
if ( (rDelta > 0.00) && (CurrentRate <= 5.00) ) chippersat::IncThrusterGroupLevel_SingleStep(THGROUP_ATT_BANKRIGHT, rDelta);
else if ( (rDelta < 0.00) && (CurrentRate >= -5.00) ) chippersat::IncThrusterGroupLevel_SingleStep(THGROUP_ATT_BANKLEFT, -rDelta);
// Yaw Inputs
CurrentRate = YawV;
CommandedRate = asin(input.y)*DEG;
double yDelta = (-CommandedRate + CurrentRate);
if ( (yDelta > 0.00) && (CurrentRate >= -5.00) ) chippersat::IncThrusterGroupLevel_SingleStep(THGROUP_ATT_YAWRIGHT, yDelta);
else if ( (yDelta < 0.00) && (CurrentRate <= 5.00) ) chippersat::IncThrusterGroupLevel_SingleStep(THGROUP_ATT_YAWLEFT, -yDelta);
//// Debuggery
//sprintf(oapiDebugString(), "X %0.3f, Y %0.3f, Z %0.3f", tgtVector.x, tgtVector.y, tgtVector.z);
//sprintf(oapiDebugString(), "X %0.3f, Y %0.3f, Z %0.3f", input.x, input.y, input.z);
//sprintf(oapiDebugString(), "Pitch %0.3f, Roll %0.3f, Yaw %0.3f", PitchV, RollV, YawV);
//sprintf(oapiDebugString(), "Pitch %0.3f, Roll %0.3f, Yaw %0.3f", pDelta, rDelta, yDelta);
}// --------------------------------------------------------------
// ==============================================================
// Overloaded callback functions
// ==============================================================
// --------------------------------------------------------------
// Set vessel class parameters
// --------------------------------------------------------------
// ==============================================================
// Some vessel parameters
// ==============================================================
const double MASS = 1815.0;
const double FUELMASS = 10000;
const double ISP = 3e4;
const double MAXMAINTH = 500000;
const double MAXHOVERTH = 35000;
const double MAXRCSTH = 8000;
// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void chippersat::clbkSetClassCaps (FILEHANDLE cfg)
{
SetEmptyMass (1863.0);
SetSize (4);
SetCW (0.7, 0.7, 0.7, 0.4);
SetCrossSections (_V(42.19, 34.58, 38.11));
SetRotDrag (_V(0.4,0.4,0.4));
SetPMI (_V(7.16,4.08,7.27));
SetCameraOffset (_V(0,0.8,0));
SetDockParams (_V(0,1.3,-1), _V(0,1,0), _V(0,0,-1));
SetTouchdownPoints (_V(4,-5.9,-4),_V(0,-5.9,4),_V(0,-5.9,-4));
SetSurfaceFrictionCoeff (0.4, 0.4);
// propellant resource
PROPELLANT_HANDLE hpr = CreatePropellantResource (FUELMASS);
// ***************** thruster definitions *******************
THRUSTER_HANDLE th_main, th_hover;
THRUSTER_HANDLE th_rcs[24], th_group[4];
PARTICLESTREAMSPEC contrail_main = {
0, 5.0, 16, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
};
PARTICLESTREAMSPEC contrail_hover = {
0, 5.0, 8, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
};
PARTICLESTREAMSPEC exhaust_main = {
0, 2.0, 20, 200, 0.05, 0.1, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
};
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
};
th_main = CreateThruster (_V(0,-4.35,0), _V(0,1,0), MAXMAINTH, hpr, ISP);
CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
AddExhaust (th_main, 8, 1, _V(0,-4.35,0), _V(0,1,0));
th_hover = CreateThruster (_V(0,-4.35,0), _V(0,1,0), MAXHOVERTH, hpr, ISP);
CreateThrusterGroup (&th_hover, 1, THGROUP_HOVER);
AddExhaust (th_hover, 8, 1, _V(0,-4.35,0), _V(0,1,0));
AddExhaustStream (th_hover, _V(0,-10,0), &contrail_hover);
AddExhaustStream (th_main, _V(0,-10,0), &contrail_main);
AddExhaustStream (th_hover, _V(0,-5,0), &exhaust_hover);
AddExhaustStream (th_main, _V(0,-5,0), &exhaust_main);
th_rcs[ 0] = CreateThruster (_V(0,1.3,2), _V(0,0,-1), MAXRCSTH, hpr, ISP);
th_rcs[ 1] = CreateThruster (_V(0,-1.3,2), _V(0,0,-1), MAXRCSTH, hpr, ISP);
th_rcs[ 2] = CreateThruster (_V(0,1.3,2), _V(0,0,-1), MAXRCSTH, hpr, ISP);
th_rcs[ 3] = CreateThruster (_V(0,-1.3,2), _V(0,0,-1), MAXRCSTH, hpr, ISP);
th_rcs[ 4] = CreateThruster (_V(0,1.3,-2), _V(0,0,1),MAXRCSTH, hpr, ISP);
th_rcs[ 5] = CreateThruster (_V(0,-1.3,-2), _V(0,0,1), MAXRCSTH, hpr, ISP);
th_rcs[ 6] = CreateThruster (_V(0,1.3,-2), _V(0,0,1), MAXRCSTH, hpr, ISP);
th_rcs[ 7] = CreateThruster (_V(0,-1.3,2), _V(0,0,1), MAXRCSTH, hpr, ISP);
th_rcs[ 8] = CreateThruster (_V(2,1.3,0), _V(-1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[ 9] = CreateThruster (_V(2,-1.3,0),_V(-1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[10] = CreateThruster (_V(2,1.3,0), _V(-1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[11] = CreateThruster (_V(2,-1.3,0), _V(-1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[12] = CreateThruster (_V(-2,1.3,0), _V(1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[13] = CreateThruster (_V(-2,-1.3,0),_V(1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[14] = CreateThruster (_V(-2,1.3,0), _V(1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[15] = CreateThruster (_V(-2,-1.3,0), _V(1,0,0), MAXRCSTH, hpr, ISP);
th_rcs[16] = CreateThruster (_V(-2.287,-1.5,-2.126), _V(0,0,1), MAXRCSTH, hpr, ISP);
th_rcs[17] = CreateThruster (_V(2.287,-1.5,2.126), _V(0,0,-1), MAXRCSTH, hpr, ISP);
th_rcs[18] = CreateThruster (_V(-2.126,-1.5,2.287), _V(0,0,-1), MAXRCSTH, hpr, ISP);
th_rcs[19] = CreateThruster (_V(2.126,-1.5,-2.287), _V(0,0,1), MAXRCSTH, hpr, ISP);
th_rcs[20] = CreateThruster (_V(-1.8,-1.5,-1.8), _V(0,-1,0), MAXRCSTH, hpr, ISP);
th_rcs[21] = CreateThruster (_V(1.8,-1.5,1.8), _V(0,-1,0), MAXRCSTH, hpr, ISP);
th_rcs[22] = CreateThruster (_V(-1.8,-2.6,1.8), _V(0,1,0), MAXRCSTH, hpr, ISP);
th_rcs[23] = CreateThruster (_V(1.8,-2.6,-1.8), _V(0,1,0), MAXRCSTH, hpr, ISP);
th_group[0] = th_rcs[2];
th_group[1] = th_rcs[7];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_PITCHUP);
th_group[0] = th_rcs[3];
th_group[1] = th_rcs[6];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_PITCHDOWN);
th_group[0] = th_rcs[8];
th_group[1] = th_rcs[13];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_BANKLEFT);
th_group[0] = th_rcs[9];
th_group[1] = th_rcs[12];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_BANKRIGHT);
th_group[0] = th_rcs[8];
th_group[1] = th_rcs[9];
th_group[2] = th_rcs[10];
th_group[3] = th_rcs[11];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_LEFT);
th_group[0] = th_rcs[12];
th_group[1] = th_rcs[13];
th_group[2] = th_rcs[14];
th_group[3] = th_rcs[15];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_RIGHT);
th_group[0] = th_rcs[18];
th_group[1] = th_rcs[19];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);
th_group[0] = th_rcs[16];
th_group[1] = th_rcs[17];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);
th_group[0] = th_rcs[22];
th_group[1] = th_rcs[23];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_BACK);
th_group[0] = th_rcs[20];
th_group[1] = th_rcs[21];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_FORWARD);
th_group[0] = th_rcs[0];
th_group[1] = th_rcs[1];
th_group[2] = th_rcs[2];
th_group[3] = th_rcs[3];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);
th_group[0] = th_rcs[4];
th_group[1] = th_rcs[5];
th_group[2] = th_rcs[6];
th_group[3] = th_rcs[7];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN); //Really ATT__FORW, cause 9 is ahead of 6 on number pad
AddExhaust (th_rcs [0], 1, 0.1, _V(0,1.3,2), _V(0,0,1));
AddExhaust (th_rcs [1], 1, 0.1, _V(0,-1.0,2), _V(0,0,1));
AddExhaust (th_rcs [4], 1, 0.1, _V(0,1.3,-2), _V(0,0,-1));
AddExhaust (th_rcs [5], 1, 0.1, _V(0,-1.0,-2), _V(0,0,-1));
AddExhaust (th_rcs [6], 1, 0.1, _V(0,1.3,-2), _V(0,0,-1));
AddExhaust (th_rcs [3], 1, 0.1, _V(0,-1.0,2), _V(0,0,1));
AddExhaust (th_rcs [2], 1, 0.1, _V(0,1.3,2), _V(0,0,1));
AddExhaust (th_rcs [7], 1, 0.1, _V(0,-1.0,-2), _V(0,0,-1));
AddExhaust (th_rcs [8], 1, 0.1, _V(2,1.3,0), _V(1,0,0));
AddExhaust (th_rcs [9], 1, 0.1, _V(2,-1.0,0), _V(1,0,0));
AddExhaust (th_rcs [12], 1, 0.1, _V(-2,1.3,0), _V(-1,0,0));
AddExhaust (th_rcs [13], 1, 0.1, _V(-2,-1.0,0), _V(-1,0,0));
AddExhaust (th_rcs [16], 2, 0.1, _V(-2.287,-1.5,-2.126), _V(0,0,-1));
AddExhaust (th_rcs [17], 2, 0.1, _V(2.287,-1.5,2.126), _V(0,0,1));
AddExhaust (th_rcs [18], 2, 0.1, _V(-2.126,-1.5,2.287), _V(0,0,1));
AddExhaust (th_rcs [19], 2, 0.1, _V(2.126,-1.5,-2.287), _V(0,0,-1));
AddExhaust (th_rcs [20], 2, 0.1, _V(-1.8,-1.5,-1.8), _V(0,1,0));
AddExhaust (th_rcs [21], 2, 0.1, _V(1.8,-1.5,1.8), _V(0,1,0));
AddExhaust (th_rcs [22], 2, 0.1, _V(-1.8,-2.6,1.8), _V(0,-1,0));
AddExhaust (th_rcs [23], 2, 0.1, _V(1.8,-2.6,-1.8), _V(0,-1,0));
int i;
static VECTOR3 beaconpos[3] = {{-0.875,0.287,2.033},{0.971,1.24,-1.930},{0.996,-0.781,-1.980}};
static VECTOR3 beaconcol[3] = {{.1, .2, .992},{1,0,0},{0,1,0}};
for (i = 0; i < 3; i++) {
beacon[i].shape = (i < 3 ? BEACONSHAPE_STAR : BEACONSHAPE_DIFFUSE);
beacon[i].pos = beaconpos+i;
beacon[i].col = beaconcol+i;
beacon[i].size = (i < 3 ? 0.7 : 0.71);
beacon[i].falloff = (i < 3 ? 0.6 : 0.61);
beacon[i].period = (i < 1 ? 13 : 9);
beacon[i].duration = (i < 1 ? 7 : 5);
beacon[i].tofs = (i < 1 ? 2 :i < 2 ? 3 :5);
beacon[i].active = false;
AddBeacon (beacon+i);
}
// visual specs
AddMesh ("chippersat");
// Now it is necessary to tune Payload Manager for your ship
// default position and orientation for payload slots:
PM_SetDefaultAttachmentParams(_V(1, 0, 0), _V(0, 1, 0), _V(0, 0, 1));
// the special definition for default position and orientation for payload slot 0 (up-forward with 30 deg pitch):
PM_SetSlotAttachmentParams(0, _V(1, 0, 0), _V(0, 1, 0), _V(0,0,1));
// the special definition for default position and orientation for payload slot 1 (down-forward with -30 deg pitch):
PM_SetSlotAttachmentParams(1, _V(1,0,0), _V(0,1,0), _V(0,0,1));
// time interval between payload separation, s (1 second by default):
PM_SetDetachInterval(0.5);
// speed of payload separation, m/s (1 m/s by default):
PM_SetDetachSpeed(1.5);
// transfer control focus to separated payload if it allows control focus (true by default):
PM_SetSendFocus(false);
// let Payload Manager to know Principal Moments of Inertia (PMI) of vehicle ship:
PM_SetVehiclePMI(_V(6.57,6.66,3.70));
// let Payload Manager to know Cross Sections (CS) of vehicle ship and rules of calculating total cross sections:
PM_SetVehicleCS (_V(41.58, 36.06, 34.60),_V(0,0,1));
// maximum number of payloads capability for your vehicle ship (10 by default):
PM_SetMaximumPayloadsNumber(11);
// setting period of refreshing PMI and CS on 10 seconds
PM_SetCapsRefreshPeriod(10);
}
// --------------------------------------------------------------
// Read status from scenario file
// --------------------------------------------------------------
void chippersat::clbkLoadStateEx (FILEHANDLE scn, void *vs)
{
char *line;
while (oapiReadScenario_nextline (scn, line)) {
if (!_strnicmp (line, "PAN", 3)) {
sscanf (line+3, "%d%lf", &pan_status, &pan_proc);
}
else if (!_strnicmp (line, "ANIMATED_THING", 14)) {
int intToBoolTemp; // MSVC's sscanf doesn't have a format modifier to read a 8-bit int value (other than literally the character itself)
sscanf (line + 14, "%i %1f", &intToBoolTemp, &radarflag_proc);
shouldAnimateTheThing = intToBoolTemp != 0;
} else {
PM_LoadState(line);
ParseScenarioLineEx (line, vs);
}
}
SetAnimation (anim_pan, pan_proc);
SetAnimation (anim_radarflag, radarflag_proc);
}
// --------------------------------------------------------------
// Save status to scenario file
// --------------------------------------------------------------
void chippersat::clbkSaveState (FILEHANDLE scn)
{
char cbuf[256];
SaveDefaultState (scn);
sprintf (cbuf, "%d %0.4f", pan_status, pan_proc);
oapiWriteScenario_string (scn, "PAN", cbuf);
char buf [256];
sprintf (buf, "%i %1f", (int)shouldAnimateTheThing, radarflag_proc);
oapiWriteScenario_string (scn, "ANIMATED_THING", buf);
baseClass::clbkSaveState(scn);
}
void chippersat::clbkPreStep (double simt, double simdt, double mjd)
{
VECTOR3 rVel, rPos, gPos;
OBJHANDLE rBody = GetGravityRef(); // Get current an object handle 'rBody' for the celestial body currently being orbited.
GetGlobalPos(gPos); // Get position of vessel in global frame.
GetRelativePos(rBody,rPos); // Get position of vessel relative to reference body.
GetRelativeVel(rBody,rVel); // Get velocity of vessel relative to reference body.
VECTOR3 horizon = crossp(rVel,rPos); // Use cross-product of 'rVel' and 'rPos' to find horizon reference.
VECTOR3 vPrograde; // Prograde velocity vector in vessel coordinates
Global2Local((rVel + gPos), vPrograde); // To find our prograde vector in vessel coordinates we need to combine gPos with rVel because Global2Local normally converts positions, not velocities.
VECTOR3 vNormal; // Orbit Normal vector in vessel coordinates
Global2Local(chippersat::RotateVector((rVel+gPos),horizon,90), vNormal); // We find our normal vector by repeating the process to find prograde and then rotating it 90 degrees about the 'horizon'.
// ==============================================================
// This vessel is a "Tail-sitter" who's axis of thrust aligned with the Y axis.
// Because Orbiter's default autopilots assume that the vessel's axis of thrust is along the Z+ axis we need to over-ride them.
// The following code checks to see if a default autopilot is active and if it is, activates the coorisonding over-ride function.
// ==============================================================
if (GetNavmodeState(1)==true) AUTOPILOT = Off; // NavmodeState(1) is the default Killrot program. This function did not need to be over-ridden so the custom autopilot stays off.
if (GetNavmodeState(2)==true) AUTOPILOT = Off; // NavmodeState(2) is the default Horizon Level program. This function did not get over-ridden either.
if (GetNavmodeState(3)==true) AUTOPILOT = Prograde; // Set autopilot to prograde mode.
if (GetNavmodeState(4)==true) AUTOPILOT = Retrograde; // Set autopilot to retrograde mode.
if (GetNavmodeState(5)==true) AUTOPILOT = Normal; // Set autopilot to orbit-normal mode.
if (GetNavmodeState(6)==true) AUTOPILOT = Antinormal; // Set autopilot to anti-normal mode.
if (GetNavmodeState(7)==true) AUTOPILOT = Hover; // Set autopilot to decent/hover mode.
// Implement autopilot control inputs.
if (AUTOPILOT==Prograde) chippersat::OrientForBurn( vPrograde);
if (AUTOPILOT==Retrograde) chippersat::OrientForBurn(-vPrograde);
if (AUTOPILOT==Normal) chippersat::OrientForBurn( vNormal);
if (AUTOPILOT==Antinormal) chippersat::OrientForBurn(-vNormal);
//if (AUTOPILOT==Hover) *Descent/Hover autopilot not yet implimented*
}
void chippersat::clbkPostStep (double simt, double simdt, double mjd)
{
// Animate Solar Panels
if (pan_status >= DOOR_CLOSING) {
double da = simdt * SOLARPANEL_OPERATING_SPEED;
PlayVesselWave(MyID,SOLARPANELSOUND,NOLOOP,255);
if (pan_status == DOOR_CLOSING) {
if (pan_proc > 0.0) pan_proc = max (0.0, pan_proc-da);
else pan_status = DOOR_CLOSED;
PlayVesselWave(MyID,SOLARPANELSOUND,NOLOOP,255);
} else {
if (pan_proc < 1.0) pan_proc = min (1.0, pan_proc+da);
else pan_status = DOOR_OPEN;
}
SetAnimation (anim_pan, pan_proc);
}
// Animate Radar Flag
if (shouldAnimateTheThing) {
double da = simdt * RADARFLAG_OPERATING_SPEED;
radarflag_proc = fmod (radarflag_proc + da, 1.0);
PlayVesselWave(MyID,RADARFLAGSOUND,NOLOOP,115);
SetAnimation (anim_radarflag, radarflag_proc);
}
{
// Translating clbkPostStep to PayloadManager
baseClass::clbkPostStep(simt, simdt, mjd);
/* Here you can place your poststep procedures
........
*/
if(j_timer < 0)
j_timer += simdt;
}
}
// --------------------------------------------------------------
// Keyboard interface handler (buffered key events)
// --------------------------------------------------------------
int chippersat::clbkConsumeBufferedKey (DWORD key, bool down, char *kstate)
{
if (!down) return 0; // only process keydown events
if (KEYMOD_CONTROL (kstate)) {
switch (key) {
case OAPI_KEY_DIVIDE: // enable/disable RCS
if (SetAttitudeMode (GetAttitudeMode() >= 1 ? 0 : 1));
return 1;
case OAPI_KEY_1:
PM_DetachPayloadByIndex(0);
return 1;
case OAPI_KEY_2:
PM_DetachPayloadByIndex(1);
return 1;
case OAPI_KEY_3:
PM_DetachPayloadByIndex(2);
return 1;
case OAPI_KEY_4:
PM_DetachPayloadByIndex(3);
return 1;
case OAPI_KEY_5:
PM_DetachPayloadByIndex(4);
return 1;
case OAPI_KEY_6:
PM_DetachPayloadByIndex(5);
return 1;
case OAPI_KEY_7:
PM_DetachPayloadByIndex(6);
return 1;
case OAPI_KEY_8:
PM_DetachPayloadByIndex(7);
return 1;
case OAPI_KEY_9:
PM_DetachPayloadByIndex(8);
return 1;
case OAPI_KEY_0:
PM_DetachPayloadByIndex(9);
return 1;
}
}else{
switch (key) {
case OAPI_KEY_1: // deploy/retract solar panels
RevertSolarPanels();
return 1;
case OAPI_KEY_2: // start/stop radarflag
shouldAnimateTheThing = !shouldAnimateTheThing;
return 1;
case OAPI_KEY_J:
// Pressing J-key will starting payloads jettisoning sequence
PM_BeginDetachPayloads();
return 1;
case OAPI_KEY_7:
for (int i = 0; i < 3; i++) {
beacon[0].active = true;
beacon[1].active = true;
beacon[2].active = true;
return 1;
}
case OAPI_KEY_8:
for (int i = 0; i < 3; i++) {
beacon[0].active = false;
beacon[1].active = false;
beacon[2].active = false;
return 1;
}
}
}
return 0;
}
void chippersat::clbkPostCreation ()
{
MyID=ConnectToOrbiterSoundDLL(GetHandle());
SetMyDefaultWaveDirectory("Sound\\_CustomVesselsSounds\\Chippersat\\");
RequestLoadVesselWave(MyID,SOLARPANELSOUND,"mypanelopening.wav",EXTERNAL_ONLY_FADED_CLOSE);
RequestLoadVesselWave(MyID,RADARFLAGSOUND,"radflagstart.wav",BOTHVIEW_FADED_CLOSE);
}
bool chippersat::clbkLoadVC (int id)
{
SetMeshVisibilityMode (AddMesh (vcmesh_tpl = oapiLoadMeshGlobal ("chippersat_vc")), MESHVIS_VC);
SetCameraOffset (_V(0,0.3,1)); SetCameraDefaultDirection (_V(0,0,1));
SetCameraRotationRange (RAD*180, RAD*180, RAD*180, RAD*180);
SetCameraShiftRange (_V(0,0,0.1), _V(-0.2,0,0), _V(0.2,0,0));
oapiVCSetNeighbours(-2, 2, 3, -3);
VCMFDSPEC mfd;
VCHUDSPEC hud;
hud.nmesh = 1;//WHICH MECH NUMBER
hud.ngroup = 53;//HUD MESH GROUP
hud.hudcnt = _V(.132,-1.027, 4.434);
hud.size = 4;
oapiVCRegisterHUD(&hud);
mfd.ngroup = 47;//LEFT MFD
mfd.nmesh = 1; //WHICH MECH NUMBER
oapiVCRegisterMFD(0, &mfd);
mfd.ngroup = 48;//RIGHT MFD
mfd.nmesh = 1; //WHICH MECH NUMBER
oapiVCRegisterMFD(1, &mfd);
return 1;
}
// Scenario Editor definations
DLLCLBK void secInit (HWND hEditor, OBJHANDLE hVessel){
//Here you can define your own Scenario Editor vessel-specific pages
//...
//Define PayloadManager Scenario Editor interface
PayloadManager::DefineScenarioEditorPage(hEditor, hVessel);
}
// ==============================================================
// API callback interface
// ==============================================================
// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
return new chippersat (hvessel, flightmodel);
}
// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
if (vessel) delete (chippersat*)vessel;
}