From ce174afcf452f6145faffe6f6122d3fa6af1c4cf Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sat, 26 Aug 2023 16:05:13 -0400 Subject: [PATCH 01/12] Add new CreateAirfoil4 function --- Orbitersdk/include/OrbiterAPI.h | 13 ++++++- Orbitersdk/include/VesselAPI.h | 34 +++++++++++++++++ Src/Orbiter/Vessel.cpp | 65 ++++++++++++++++++++++++++++----- Src/Orbiter/Vessel.h | 5 ++- 4 files changed, 105 insertions(+), 12 deletions(-) diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 8f372c420..6fa8dfde2 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -1623,6 +1623,16 @@ typedef void (*AirfoilCoeffFuncEx)( // Contains additional parameters (calling vessel and pointer to // user-defined data) +typedef void (*AirfoilCoeffFuncEx2)( + VESSEL* v, + double alpha, double beta, double gamma, + double M, double Re, void* context, + double* CA, double* CN, double* CY, + double* Cl, double* Cm, double* Cn); +// Further extended version of aerodynamic coefficients callback function +// Contains additional parameters (calling vessel and pointer to +// user-defined data for all force and moment coefficients) + // =========================================================================== /// \ingroup defines @@ -1638,7 +1648,8 @@ typedef void (*AirfoilCoeffFuncEx)( */ typedef enum { LIFT_VERTICAL, ///< lift direction is vertical (e.g. elevator) - LIFT_HORIZONTAL ///< lift direction is horizontal (e.g. rudder) + LIFT_HORIZONTAL, ///< lift direction is horizontal (e.g. rudder) + FORCE_AND_MOMENT ///< complex model of forces and moments along and about all axes } AIRFOIL_ORIENTATION; //@} diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index b5252582b..a0d2fe38c 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -1484,6 +1484,40 @@ class OAPIFUNC VESSEL { */ AIRFOILHANDLE CreateAirfoil3 (AIRFOIL_ORIENTATION align, const VECTOR3 &ref, AirfoilCoeffFuncEx cf, void *context, double c, double S, double A) const; + /** + * \brief Creates a new airfoil and defines its aerodynamic properties. + * \param ref centre of pressure in vessel coordinates [m], nominally this shoud be at the CoM. + * \param cf pointer to coefficient callback function (see notes) + * \param context pointer to data block passed to cf callback function + * \param c airfoil chord length [m] + * \param S wing area [m2] + * \param A wing aspect ratio + * \return Handle for the new airfoil. + * \note This method is an extension to \ref CreateAirfoil3, using a + * more versatile coefficient callback function. + * \note AirfoilCoeffFuncEx has the following interface: + * \code + * void (*AirfoilCoeffFuncEx2)( + * VESSEL* v, + * double alpha, double beta, double gamma, + * double M, double Re, void* context, + * double* CA, double* CN, double* CY, + * double* Cl, double* Cm, double* Cn); + * \endcode + * where \e v is a pointer to the calling vessel instance, and + * \a context is the pointer passed to CreateAirfoil4. It can be + * used to make available to the callback function any additional + * parameters required to calculate the lift and drag coefficients. + * The coefficients: CA, CN, and CY are force coefficients along the + * vessel's Z, Y, and X body axes respectively. + * The coefficients: Cl, Cm, and Cn are moment coefficients about the + * vessel's Z, X, and Y body axes respectively. + * All other parameters are identical to AirfoilCoeffFunc (see + * \ref CreateAirfoil). + * \sa CreateAirfoil, CreateAirfoil2, CreateAirfoil3, EditAirfoil, DelAirfoil + */ + AIRFOILHANDLE CreateAirfoil4(const VECTOR3& ref, AirfoilCoeffFuncEx2 cf, void* context, double c, double S, double A) const; + /** * \brief Returns the parameters of an existing airfoil. * \param [in] hAirfoil airfoil handle diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 2b87c8bfa..4924f5156 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -1767,6 +1767,29 @@ AirfoilSpec *Vessel::CreateAirfoil (AIRFOIL_ORIENTATION align, const Vector &ref // ============================================================== +AirfoilSpec* Vessel::CreateAirfoil(AIRFOIL_ORIENTATION align, const Vector& ref, AirfoilCoeffFuncEx2 cf, void* context, double c, double S, double A) +{ + AirfoilSpec* af, ** tmp = new AirfoilSpec * [nairfoil + 1]; TRACENEW + if (nairfoil) { + memcpy(tmp, airfoil, nairfoil * sizeof(AirfoilSpec*)); + delete[]airfoil; + } + airfoil = tmp; + + af = airfoil[nairfoil++] = new AirfoilSpec; TRACENEW + af->version = 2; + af->align = align; + af->ref.Set(ref); + af->cf = (AirfoilCoeffFunc)cf; + af->context = context; + af->c = c; + af->S = S; + af->A = A; + return af; +} + +// ============================================================== + bool Vessel::GetAirfoilParam (AirfoilSpec *af, VECTOR3 *ref, AirfoilCoeffFunc *cf, void **context, double *c, double *S, double *A) { for (DWORD i = 0; i < nairfoil; i++) { @@ -4000,6 +4023,7 @@ void Vessel::UpdateAerodynamicForces () double aoa = atan2 (-sp.airvel_ship.y,sp.airvel_ship.z); // angle of attack double beta = atan2 (-sp.airvel_ship.x,sp.airvel_ship.z); // lateral angle of attack (slip) + double gamma = (!sp.airvel_ship.y) ? atan2(-sp.airvel_ship.x, -sp.airvel_ship.y) : 0; const double mu = 1.7894e-5; // viscosity coefficient dummy - MAKE VARIABLE! double Re0 = sp.atmrho * sp.airspd / mu; // template for Reynolds coefficient (to be multiplied by chord length) @@ -4032,31 +4056,46 @@ void Vessel::UpdateAerodynamicForces () Vector ldir (0, sp.airvel_ship.z, -sp.airvel_ship.y); ldir.unify(); // lift direction (vertical on drag and transversal ship axis) Vector sdir (sp.airvel_ship.z, 0, -sp.airvel_ship.x); sdir.unify(); // sidelift direction (vertical on drag and vertical ship axis) double lift, drag, S; - double Cl, Cm, Cd; // lift, moment, drag coeffs + double CL, CD; // lift, drag coeffs (used by AirfoilCoeffFunc and AirfoilCoeffFuncEx) + double CA, CN, CY; //force coefficients along Orbiter Z, Y, X axes (AirfoilCoeffFuncEx2) + double Cl, Cm, Cn; //moment coefficients about Orbiter Z, X, Y axes (AirfoilCoeffFuncEx2 uses Cl and Cn) // airfoil lift+drag components for (i = 0; i < nairfoil; i++) { AirfoilSpec *af = airfoil[i]; if (af->align == LIFT_VERTICAL) { if (af->version == 0) - af->cf (aoa, sp.atmM, Re0*af->c, &Cl, &Cm, &Cd); + af->cf (aoa, sp.atmM, Re0*af->c, &CL, &Cm, &CD); else - ((AirfoilCoeffFuncEx)af->cf)((VESSEL*)modIntf.v, aoa, sp.atmM, Re0*af->c, af->context, &Cl, &Cm, &Cd); + ((AirfoilCoeffFuncEx)af->cf)((VESSEL*)modIntf.v, aoa, sp.atmM, Re0*af->c, af->context, &CL, &Cm, &CD); if (af->S) S = af->S; else S = fabs(ddir.z)*cs.z + fabs(ddir.y)*cs.y; // use projected vessel CS as reference area - AddForce (ldir*(lift=(Cl*sp.dynp*S)) + ddir*(drag=(Cd*sp.dynp*S)), af->ref); + AddForce (ldir*(lift=(CL*sp.dynp*S)) + ddir*(drag=(CD*sp.dynp*S)), af->ref); if (Cm) Amom_add.x += Cm*sp.dynp*af->S*af->c; Lift += lift, Drag += drag; - } else { // horizontal lift component + } else if (af->align == LIFT_HORIZONTAL) { // horizontal lift component if (af->version == 0) - af->cf (beta, sp.atmM, Re0*af->c, &Cl, &Cm, &Cd); + af->cf (beta, sp.atmM, Re0*af->c, &CL, &Cm, &CD); else - ((AirfoilCoeffFuncEx)af->cf)((VESSEL*)modIntf.v, beta, sp.atmM, Re0*af->c, af->context, &Cl, &Cm, &Cd); + ((AirfoilCoeffFuncEx)af->cf)((VESSEL*)modIntf.v, beta, sp.atmM, Re0*af->c, af->context, &CL, &Cm, &CD); if (af->S) S = af->S; else S = fabs(ddir.z)*cs.z + fabs(ddir.x)*cs.z; // use projected vessel CS as reference area - AddForce (sdir*(Cl*sp.dynp*S) + ddir*(drag=(Cd*sp.dynp*S)), af->ref); + AddForce (sdir*(CL*sp.dynp*S) + ddir*(drag=(CD*sp.dynp*S)), af->ref); if (Cm) Amom_add.y += Cm*sp.dynp*af->S*af->c; Drag += drag; + } else if (af->align == FORCE_AND_MOMENT) { + ((AirfoilCoeffFuncEx2)af->cf)((VESSEL*)modIntf.v, aoa, beta, gamma, sp.atmM, Re0 * af->c, af->context, &CA, &CN, &CY, &Cl, &Cm, &Cn); + if (af->S) S = af->S; + else S = fabs(ddir.z) * cs.z + fabs(ddir.x) * cs.z; // use projected vessel CS as reference area + + Vector AeroForce((CY * S) * sp.dynp, (CN * S) * sp.dynp, (CA * S) * sp.dynp); + + AddForce(AeroForce, af->ref); + + Amom_add.x += Cm * sp.dynp * af->S * af->c; + Amom_add.y -= Cn * sp.dynp * af->S * af->c; + Amom_add.z -= Cl * sp.dynp * af->S * af->c; + } } @@ -4089,8 +4128,8 @@ void Vessel::UpdateAerodynamicForces () for (i = 0; i < ndragel; i++) { double lvl = *dragel[i]->drag; if (lvl) { - Cd = lvl*dragel[i]->factor; - drag = Cd*sp.dynp; + CD = lvl*dragel[i]->factor; + drag = CD*sp.dynp; AddForce (ddir*drag, dragel[i]->ref); Drag += drag; } @@ -8373,6 +8412,12 @@ AIRFOILHANDLE VESSEL::CreateAirfoil3 (AIRFOIL_ORIENTATION align, const VECTOR3 & return (AIRFOILHANDLE)vessel->CreateAirfoil (align, r, cf, context, c, S, A); } +AIRFOILHANDLE VESSEL::CreateAirfoil4 (const VECTOR3& ref, AirfoilCoeffFuncEx2 cf, void* context, double c, double S, double A) const +{ + Vector r(MakeVector(ref)); + return (AIRFOILHANDLE)vessel->CreateAirfoil(FORCE_AND_MOMENT, r, cf, context, c, S, A); +} + bool VESSEL::GetAirfoilParam (AIRFOILHANDLE hAirfoil, VECTOR3 *ref, AirfoilCoeffFunc *cf, void **context, double *c, double *S, double *A) const { return vessel->GetAirfoilParam ((AirfoilSpec*)hAirfoil, ref, cf, context, c, S, A); diff --git a/Src/Orbiter/Vessel.h b/Src/Orbiter/Vessel.h index 83ebfc09f..db742c1cf 100644 --- a/Src/Orbiter/Vessel.h +++ b/Src/Orbiter/Vessel.h @@ -105,7 +105,7 @@ typedef struct { // obsolete exhaust render definition } OldExhaustSpec; typedef struct { // airfoil definition - int version; // 0: uses AirfoilCoeffFunc, 1: uses AirfoilCoeffFuncEx + int version; // 0: uses AirfoilCoeffFunc, 1: uses AirfoilCoeffFuncEx, 3: uses AirfoilCoeffFuncEx2 AIRFOIL_ORIENTATION align; // vertical or horizontal Vector ref; // lift,drag attack reference point AirfoilCoeffFunc cf; // pointer to coefficients callback function @@ -805,6 +805,9 @@ class Vessel: public VesselBase { AirfoilSpec *CreateAirfoil (AIRFOIL_ORIENTATION align, const Vector &ref, AirfoilCoeffFuncEx cf, void *context, double c, double S, double A); // Create a new airfoil; extended version + AirfoilSpec* CreateAirfoil(AIRFOIL_ORIENTATION align, const Vector& ref, AirfoilCoeffFuncEx2 cf, void* context, double c, double S, double A); + // Create a new airfoil; extended force and moment version + bool GetAirfoilParam (AirfoilSpec *af, VECTOR3 *ref, AirfoilCoeffFunc *cf, void **context, double *c, double *S, double *A); // Return airfoil parameters From 97df5e70d960fa63d93e0b83f595ae3287677ca1 Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sun, 27 Aug 2023 14:46:35 -0400 Subject: [PATCH 02/12] fix sign error --- Src/Orbiter/Vessel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 4924f5156..b1e14e74a 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -4088,9 +4088,11 @@ void Vessel::UpdateAerodynamicForces () if (af->S) S = af->S; else S = fabs(ddir.z) * cs.z + fabs(ddir.x) * cs.z; // use projected vessel CS as reference area - Vector AeroForce((CY * S) * sp.dynp, (CN * S) * sp.dynp, (CA * S) * sp.dynp); + Vector AeroForce((CY * S) * sp.dynp, (CN * S) * sp.dynp, -(CA * S) * sp.dynp); AddForce(AeroForce, af->ref); + Lift = dotp(AeroForce, ldir); + Drag = Lift = dotp(AeroForce, ddir); Amom_add.x += Cm * sp.dynp * af->S * af->c; Amom_add.y -= Cn * sp.dynp * af->S * af->c; From 0b74561fbf5508f1bd01ba5e0f2024f3b7f3f092 Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Wed, 3 Jan 2024 00:05:31 -0500 Subject: [PATCH 03/12] add vector function --- Orbitersdk/include/OrbiterAPI.h | 5 +++-- Src/Orbiter/Vessel.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 6fa8dfde2..77d4ce59c 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -1624,7 +1624,8 @@ typedef void (*AirfoilCoeffFuncEx)( // user-defined data) typedef void (*AirfoilCoeffFuncEx2)( - VESSEL* v, + VESSEL* v, + VECTOR3 WindDir, double alpha, double beta, double gamma, double M, double Re, void* context, double* CA, double* CN, double* CY, @@ -1644,7 +1645,7 @@ typedef void (*AirfoilCoeffFuncEx2)( * * Defines the orientation of an airfoil by the direction of the lift vector * generated (vertical or horizontal). - * \sa VESSEL::CreateAirfoil, VESSEL::CreateAirfoil2, VESSEL::CreateAirfoil3 + * \sa VESSEL::CreateAirfoil, VESSEL::CreateAirfoil2, VESSEL::CreateAirfoil3, VESSEL::CreateAirfoil4 */ typedef enum { LIFT_VERTICAL, ///< lift direction is vertical (e.g. elevator) diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index b1e14e74a..a0f2b8a69 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -4084,7 +4084,7 @@ void Vessel::UpdateAerodynamicForces () if (Cm) Amom_add.y += Cm*sp.dynp*af->S*af->c; Drag += drag; } else if (af->align == FORCE_AND_MOMENT) { - ((AirfoilCoeffFuncEx2)af->cf)((VESSEL*)modIntf.v, aoa, beta, gamma, sp.atmM, Re0 * af->c, af->context, &CA, &CN, &CY, &Cl, &Cm, &Cn); + ((AirfoilCoeffFuncEx2)af->cf)((VESSEL*)modIntf.v, -_V(sp.airvel_ship.unit().x, sp.airvel_ship.unit().y, sp.airvel_ship.unit().z), aoa, beta, gamma, sp.atmM, Re0 * af->c, af->context, &CA, &CN, &CY, &Cl, &Cm, &Cn); if (af->S) S = af->S; else S = fabs(ddir.z) * cs.z + fabs(ddir.x) * cs.z; // use projected vessel CS as reference area From 9859daa52ca3ace01a5bb26072232d12b22879e7 Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Thu, 4 Jan 2024 10:23:36 -0500 Subject: [PATCH 04/12] Fix error with Drag reporting variable --- Src/Orbiter/Vessel.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index a0f2b8a69..a9b32f41e 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -4092,7 +4092,7 @@ void Vessel::UpdateAerodynamicForces () AddForce(AeroForce, af->ref); Lift = dotp(AeroForce, ldir); - Drag = Lift = dotp(AeroForce, ddir); + Drag = dotp(AeroForce, ddir); Amom_add.x += Cm * sp.dynp * af->S * af->c; Amom_add.y -= Cn * sp.dynp * af->S * af->c; @@ -5594,10 +5594,10 @@ bool Vessel::VCRedrawEvent (int id, int event, SURFHANDLE surf) const bool Vessel::VCMouseEvent (int id, int event, Vector &p) const { - if (modIntf.v && modIntf.v->Version() >= 1) { - VECTOR3 v = _V(p.x,p.y,p.z); - return ((VESSEL2*)modIntf.v)->clbkVCMouseEvent (id, event, v); - } + if (modIntf.v && modIntf.v->Version() >= 1) { + VECTOR3 v = _V(p.x,p.y,p.z); + return ((VESSEL2*)modIntf.v)->clbkVCMouseEvent (id, event, v); + } else return false; } @@ -8897,4 +8897,4 @@ bool VESSEL4::UnregisterMFDMode (int mode) int VESSEL4::clbkNavProcess (int mode) { return mode; -} +} From 045698dd1da835cdb529d398be70893c7e555c53 Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Fri, 5 Jan 2024 01:24:12 -0500 Subject: [PATCH 05/12] start adding side-force vector --- OVP/D3D7Client/VVessel.cpp | 5 +++++ Orbitersdk/include/GraphicsAPI.h | 1 + Orbitersdk/include/VesselAPI.h | 8 ++++++++ Src/Orbiter/Vessel.cpp | 4 ++-- Src/Orbiter/Vessel.h | 6 +++++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index a39428973..9f4896ac8 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -174,6 +174,11 @@ void vVessel::UpdateRenderVectors() if (logscale) len = log(len + 1e-5) - log(1e-5); else len *= scale * 1e5; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2 * 0.5, std::string(cbuf), _V(1, 0, 1), alpha, D3DRGB(1, 0, 1)); } + if ((flag & BVF_SIDEFORCE) && vessel->GetSideForce(F)) { + sprintf(cbuf, "SF = %fN", len = length(F)); + if (logscale) len = log(len + shift) - lshift; else len *= scale; + AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.5, 0.0, 1.0)); + } } } diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index cbe6bcad3..0e5e915b4 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -319,6 +319,7 @@ typedef void *HDC; #define BFV_DRAG 0x0020 ///< Show drag vector #define BFV_TOTAL 0x0040 ///< Show total force vector #define BFV_TORQUE 0x0080 ///< Show torque vector +#define BVF_SIDEFORCE 0x0100 ///< Show side-force vector /// @} /// \defgroup favflag Bit flags for frame axis vector render options diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index a0d2fe38c..ffa15421d 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -2012,6 +2012,14 @@ class OAPIFUNC VESSEL { */ double GetDrag () const; + /** + * \brief Returns magnitude of aerodynamic side-force vector. + * \return Magnitude of drag force vector [N]. + * \note Return value is the sum of drag components from all airfoils. + * \sa GetDragVector, GetLift + */ + double GetSideForce() const; + /** * \brief Returns gravitational force vector in local vessel coordinates. * \param[out] G gravitational force vector [N] diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index a9b32f41e..51cb65f38 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -315,7 +315,7 @@ void Vessel::SetDefaultState () m_bThrustEngaged = false; bForceActive = false; rpressure = g_pOrbiter->Cfg()->CfgPhysicsPrm.bRadiationPressure; - Lift = Drag = 0.0; + Lift = Drag = SideForce = 0.0; attach_status.pname = 0; hudskp = NULL; next_hullvtx = 0; @@ -3763,7 +3763,7 @@ double Vessel::GetGravityGradientDamping () const void Vessel::UpdateBodyForces () { - Lift = Drag = 0.0; + Lift = Drag = SideForce = 0.0; if (m_thruster.size()) UpdateThrustForces (); if (CtrlSurfSyncMode) ApplyControlSurfaceLevels (); diff --git a/Src/Orbiter/Vessel.h b/Src/Orbiter/Vessel.h index db742c1cf..eac06a4e5 100644 --- a/Src/Orbiter/Vessel.h +++ b/Src/Orbiter/Vessel.h @@ -377,6 +377,10 @@ class Vessel: public VesselBase { // Returns drag vector in D (in local vessel frame). // Return value indicates if drag is present + bool GetSideForceVector(Vector& SF) const; + // Returns side-force vector in SF (in local vessel frame). + // Return value indicates if side-force is present + bool GetForceVector (Vector &F) const; // Returns total linear force vector acting on the vessel // Return value is always true @@ -1666,7 +1670,7 @@ class Vessel: public VesselBase { Vector Thrust; // linear thrust vector (sum of all thruster contributions) mutable Vector Weight; // weight vector (due to gravitational acceleration) mutable bool weight_valid; // flag for 'Weight' up to date - double Lift, Drag; // current lift and drag magnitudes + double Lift, Drag, SideForce; // current lift and drag magnitudes DWORD navmode; // bitflags for currently active navmodes struct HoverHoldAlt { // Hover hold altitude data From 64e92ac505e168ed07a5abf137f7a75fad29182d Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sat, 6 Jan 2024 00:46:33 -0500 Subject: [PATCH 06/12] add missing functions --- OVP/D3D7Client/VVessel.cpp | 2 +- Orbitersdk/include/VesselAPI.h | 14 ++++++++++++++ Src/Orbiter/Vessel.cpp | 13 +++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index 9f4896ac8..95f98877f 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -174,7 +174,7 @@ void vVessel::UpdateRenderVectors() if (logscale) len = log(len + 1e-5) - log(1e-5); else len *= scale * 1e5; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2 * 0.5, std::string(cbuf), _V(1, 0, 1), alpha, D3DRGB(1, 0, 1)); } - if ((flag & BVF_SIDEFORCE) && vessel->GetSideForce(F)) { + if ((flag & BFV_TOTAL) && vessel->GetSideForceVector(F)) { sprintf(cbuf, "SF = %fN", len = length(F)); if (logscale) len = log(len + shift) - lshift; else len *= scale; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.5, 0.0, 1.0)); diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index ffa15421d..a0b9fc2dc 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -2075,6 +2075,20 @@ class OAPIFUNC VESSEL { */ bool GetDragVector (VECTOR3 &D) const; + /** + * \brief Returns aerodynamic side-force force vector in local vessel + * coordinates. + * \param[out] SF drag vector [N] + * \return false indicates zero side-force. In that case, the returned vector + * is (0,0,0). + * \note On return, SD contains the sum of Side-force components from all + * airfoils. + * \note The side-force vector is mutually orthogonal to the Lift and Drag vectors + * \sa GetDrag, GetWeightVector, GetThrustVector, GetLiftVector, + * GetForceVector + */ + bool GetSideForceVector (VECTOR3 &SF) const; + /** * \brief Returns total force vector acting on the vessel in local * vessel coordinates. diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 51cb65f38..a5179d8cd 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -6709,6 +6709,11 @@ double VESSEL::GetDrag (void) const return vessel->Drag; } +double VESSEL::GetSideForce() const +{ + return vessel->SideForce; +} + bool VESSEL::GetWeightVector (VECTOR3 &G) const { static Vector F; @@ -6741,6 +6746,14 @@ bool VESSEL::GetDragVector (VECTOR3 &D) const return bDrag; } +bool VESSEL::GetSideForceVector(VECTOR3 &SF) const +{ + static Vector F; + bool bSideForce = vessel->GetDragVector(F); + CopyVector(F, SF); + return bSideForce; +} + bool VESSEL::GetForceVector (VECTOR3 &F) const { static Vector FF; From 20c0aa56278d06e0b2225d45709a3bedf183e5a5 Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sat, 6 Jan 2024 00:47:00 -0500 Subject: [PATCH 07/12] testing --- OVP/D3D7Client/VVessel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index 95f98877f..ba6aef64c 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -174,7 +174,7 @@ void vVessel::UpdateRenderVectors() if (logscale) len = log(len + 1e-5) - log(1e-5); else len *= scale * 1e5; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2 * 0.5, std::string(cbuf), _V(1, 0, 1), alpha, D3DRGB(1, 0, 1)); } - if ((flag & BFV_TOTAL) && vessel->GetSideForceVector(F)) { + if ((flag & BVF_SIDEFORCE) && vessel->GetSideForceVector(F)) { sprintf(cbuf, "SF = %fN", len = length(F)); if (logscale) len = log(len + shift) - lshift; else len *= scale; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.5, 0.0, 1.0)); From 867791629463f25bac6bf71202e9624997e7b87c Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sun, 7 Jan 2024 01:34:10 -0500 Subject: [PATCH 08/12] Add visual helper option --- OVP/D3D7Client/VVessel.cpp | 4 ++-- Orbitersdk/include/GraphicsAPI.h | 2 +- Src/Orbiter/OptionsPages.cpp | 1 + Src/Orbiter/Orbiter.rc | 1 + Src/Orbiter/Vessel.cpp | 6 ++++-- Src/Orbiter/resource.h | 1 + 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index ba6aef64c..d586b31a6 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -174,10 +174,10 @@ void vVessel::UpdateRenderVectors() if (logscale) len = log(len + 1e-5) - log(1e-5); else len *= scale * 1e5; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2 * 0.5, std::string(cbuf), _V(1, 0, 1), alpha, D3DRGB(1, 0, 1)); } - if ((flag & BVF_SIDEFORCE) && vessel->GetSideForceVector(F)) { + if ((flag & BFV_SIDEFORCE) && vessel->GetSideForceVector(F)) { sprintf(cbuf, "SF = %fN", len = length(F)); if (logscale) len = log(len + shift) - lshift; else len *= scale; - AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.5, 0.0, 1.0)); + AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.0392, 0.6235, 0.4941)); } } } diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 0e5e915b4..417154360 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -319,7 +319,7 @@ typedef void *HDC; #define BFV_DRAG 0x0020 ///< Show drag vector #define BFV_TOTAL 0x0040 ///< Show total force vector #define BFV_TORQUE 0x0080 ///< Show torque vector -#define BVF_SIDEFORCE 0x0100 ///< Show side-force vector +#define BFV_SIDEFORCE 0x0100 ///< Show side-force vector /// @} /// \defgroup favflag Bit flags for frame axis vector render options diff --git a/Src/Orbiter/OptionsPages.cpp b/Src/Orbiter/OptionsPages.cpp index 484735b17..2cacbec23 100644 --- a/Src/Orbiter/OptionsPages.cpp +++ b/Src/Orbiter/OptionsPages.cpp @@ -1994,6 +1994,7 @@ void OptionsPage_Forces::UpdateControls(HWND hPage) SendDlgItemMessage(hPage, IDC_OPT_VEC_THRUST, BM_SETCHECK, vecFlag & BFV_THRUST ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage(hPage, IDC_OPT_VEC_LIFT, BM_SETCHECK, vecFlag & BFV_LIFT ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage(hPage, IDC_OPT_VEC_DRAG, BM_SETCHECK, vecFlag & BFV_DRAG ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hPage, IDC_OPT_VEC_SIDEFORCE, BM_SETCHECK, vecFlag & BFV_SIDEFORCE ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage(hPage, IDC_OPT_VEC_TOTAL, BM_SETCHECK, vecFlag & BFV_TOTAL ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage(hPage, IDC_OPT_VEC_TORQUE, BM_SETCHECK, vecFlag & BFV_TORQUE ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage(hPage, IDC_OPT_VEC_LINSCL, BM_SETCHECK, vecFlag & BFV_LOGSCALE ? BST_UNCHECKED : BST_CHECKED, 0); diff --git a/Src/Orbiter/Orbiter.rc b/Src/Orbiter/Orbiter.rc index d9efc762c..dfef3646f 100644 --- a/Src/Orbiter/Orbiter.rc +++ b/Src/Orbiter/Orbiter.rc @@ -764,6 +764,7 @@ BEGIN CONTROL "Thrust",IDC_OPT_VEC_THRUST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,40,44,10 CONTROL "Lift",IDC_OPT_VEC_LIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,28,44,10 CONTROL "Drag",IDC_OPT_VEC_DRAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,40,44,10 + CONTROL "Side", IDC_OPT_VEC_SIDEFORCE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 56, 56, 44, 10 CONTROL "Total",IDC_OPT_VEC_TOTAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,56,80,10 GROUPBOX "Angular moments",IDC_STATIC2,6,80,100,26 CONTROL "Torque",IDC_OPT_VEC_TORQUE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,92,80,10 diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index a5179d8cd..dc964de31 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -4055,7 +4055,7 @@ void Vessel::UpdateAerodynamicForces () Vector ddir (-sp.airvel_ship.unit()); // freestream airflow direction (= drag direction) Vector ldir (0, sp.airvel_ship.z, -sp.airvel_ship.y); ldir.unify(); // lift direction (vertical on drag and transversal ship axis) Vector sdir (sp.airvel_ship.z, 0, -sp.airvel_ship.x); sdir.unify(); // sidelift direction (vertical on drag and vertical ship axis) - double lift, drag, S; + double lift, drag, side, S; double CL, CD; // lift, drag coeffs (used by AirfoilCoeffFunc and AirfoilCoeffFuncEx) double CA, CN, CY; //force coefficients along Orbiter Z, Y, X axes (AirfoilCoeffFuncEx2) double Cl, Cm, Cn; //moment coefficients about Orbiter Z, X, Y axes (AirfoilCoeffFuncEx2 uses Cl and Cn) @@ -4080,9 +4080,10 @@ void Vessel::UpdateAerodynamicForces () ((AirfoilCoeffFuncEx)af->cf)((VESSEL*)modIntf.v, beta, sp.atmM, Re0*af->c, af->context, &CL, &Cm, &CD); if (af->S) S = af->S; else S = fabs(ddir.z)*cs.z + fabs(ddir.x)*cs.z; // use projected vessel CS as reference area - AddForce (sdir*(CL*sp.dynp*S) + ddir*(drag=(CD*sp.dynp*S)), af->ref); + AddForce (sdir*(side = (CL*sp.dynp*S)) + ddir*(drag=(CD*sp.dynp*S)), af->ref); if (Cm) Amom_add.y += Cm*sp.dynp*af->S*af->c; Drag += drag; + SideForce += side; } else if (af->align == FORCE_AND_MOMENT) { ((AirfoilCoeffFuncEx2)af->cf)((VESSEL*)modIntf.v, -_V(sp.airvel_ship.unit().x, sp.airvel_ship.unit().y, sp.airvel_ship.unit().z), aoa, beta, gamma, sp.atmM, Re0 * af->c, af->context, &CA, &CN, &CY, &Cl, &Cm, &Cn); if (af->S) S = af->S; @@ -4093,6 +4094,7 @@ void Vessel::UpdateAerodynamicForces () AddForce(AeroForce, af->ref); Lift = dotp(AeroForce, ldir); Drag = dotp(AeroForce, ddir); + SideForce = dotp(AeroForce, sdir); Amom_add.x += Cm * sp.dynp * af->S * af->c; Amom_add.y -= Cn * sp.dynp * af->S * af->c; diff --git a/Src/Orbiter/resource.h b/Src/Orbiter/resource.h index 8a75c0d0e..5e0ba24d9 100644 --- a/Src/Orbiter/resource.h +++ b/Src/Orbiter/resource.h @@ -275,6 +275,7 @@ #define IDC_OPT_JOY_STATIC2 1103 #define IDC_OPT_JOY_STATIC3 1104 #define IDC_OPT_JOY_STATIC4 1105 +#define IDC_OPT_VEC_SIDEFORCE 1106 // Unsorted #define IDC_SCN_LIST 1090 From c47a802181f113ee910263ef867ea38eda3e6eea Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sun, 7 Jan 2024 19:40:43 -0500 Subject: [PATCH 09/12] further fixes to menu and functions --- OVP/D3D7Client/VVessel.cpp | 10 +++++----- Src/Orbiter/OptionsPages.cpp | 18 ++++++++++-------- Src/Orbiter/Vessel.cpp | 17 ++++++++++++++++- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index d586b31a6..d3715168c 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -164,6 +164,11 @@ void vVessel::UpdateRenderVectors() if (logscale) len = log(len + shift) - lshift; else len *= scale; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(1, 0, 0), alpha, D3DRGB(1, 0.5, 0.5)); } + if ((flag & BFV_SIDEFORCE) && vessel->GetSideForceVector(F)) { + sprintf(cbuf, "SF = %fN", len = length(F)); + if (logscale) len = log(len + shift) - lshift; else len *= scale; + AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.0392, 0.6235, 0.4941)); + } if ((flag & BFV_TOTAL) && vessel->GetForceVector(F)) { sprintf(cbuf, "F = %fN", len = length(F)); if (logscale) len = log(len + shift) - lshift; else len *= scale; @@ -174,11 +179,6 @@ void vVessel::UpdateRenderVectors() if (logscale) len = log(len + 1e-5) - log(1e-5); else len *= scale * 1e5; AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2 * 0.5, std::string(cbuf), _V(1, 0, 1), alpha, D3DRGB(1, 0, 1)); } - if ((flag & BFV_SIDEFORCE) && vessel->GetSideForceVector(F)) { - sprintf(cbuf, "SF = %fN", len = length(F)); - if (logscale) len = log(len + shift) - lshift; else len *= scale; - AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.0392, 0.6235, 0.4941)); - } } } diff --git a/Src/Orbiter/OptionsPages.cpp b/Src/Orbiter/OptionsPages.cpp index 2cacbec23..ef75590f4 100644 --- a/Src/Orbiter/OptionsPages.cpp +++ b/Src/Orbiter/OptionsPages.cpp @@ -2029,6 +2029,7 @@ BOOL OptionsPage_Forces::OnCommand(HWND hPage, WORD ctrlId, WORD notification, H case IDC_OPT_VEC_THRUST: case IDC_OPT_VEC_LIFT: case IDC_OPT_VEC_DRAG: + case IDC_OPT_VEC_SIDEFORCE: case IDC_OPT_VEC_TOTAL: case IDC_OPT_VEC_TORQUE: case IDC_OPT_VEC_LINSCL: @@ -2049,14 +2050,15 @@ void OptionsPage_Forces::OnItemClicked(HWND hPage, WORD ctrlId) bool check = (SendDlgItemMessage(hPage, ctrlId, BM_GETCHECK, 0, 0) == TRUE); DWORD flag; switch (ctrlId) { - case IDC_OPT_VEC: flag = BFV_ENABLE; break; - case IDC_OPT_VEC_WEIGHT: flag = BFV_WEIGHT; break; - case IDC_OPT_VEC_THRUST: flag = BFV_THRUST; break; - case IDC_OPT_VEC_LIFT: flag = BFV_LIFT; break; - case IDC_OPT_VEC_DRAG: flag = BFV_DRAG; break; - case IDC_OPT_VEC_TOTAL: flag = BFV_TOTAL; break; - case IDC_OPT_VEC_TORQUE: flag = BFV_TORQUE; break; - case IDC_OPT_VEC_LINSCL: flag = BFV_LOGSCALE; check = false; break; + case IDC_OPT_VEC: flag = BFV_ENABLE; break; + case IDC_OPT_VEC_WEIGHT: flag = BFV_WEIGHT; break; + case IDC_OPT_VEC_THRUST: flag = BFV_THRUST; break; + case IDC_OPT_VEC_LIFT: flag = BFV_LIFT; break; + case IDC_OPT_VEC_DRAG: flag = BFV_DRAG; break; + case IDC_OPT_VEC_SIDEFORCE: flag = BFV_SIDEFORCE; break; + case IDC_OPT_VEC_TOTAL: flag = BFV_TOTAL; break; + case IDC_OPT_VEC_TORQUE: flag = BFV_TORQUE; break; + case IDC_OPT_VEC_LINSCL: flag = BFV_LOGSCALE; check = false; break; case IDC_OPT_VEC_LOGSCL: flag = BFV_LOGSCALE; check = true; break; default: flag = 0; break; } diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index dc964de31..640a342bd 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -1281,6 +1281,21 @@ bool Vessel::GetDragVector (Vector &D) const // ============================================================== +bool Vessel::GetSideForceVector (Vector &SF) const +{ + if (!SideForce) { + SF.Set (0, 0, 0); + return false; + } else { + double v0 = std::hypot(sp.airvel_ship.x, sp.airvel_ship.z); + double scale = (v0 ? SideForce / v0 : 0.0); + SF.Set(0, sp.airvel_ship.z * scale, -sp.airvel_ship.x * scale); + return true; + } +} + +// ============================================================== + bool Vessel::GetForceVector (Vector &F) const { // Obtain total force vector from acceleration vector @@ -6751,7 +6766,7 @@ bool VESSEL::GetDragVector (VECTOR3 &D) const bool VESSEL::GetSideForceVector(VECTOR3 &SF) const { static Vector F; - bool bSideForce = vessel->GetDragVector(F); + bool bSideForce = vessel->GetSideForceVector(F); CopyVector(F, SF); return bSideForce; } From 670952f79e4be3f916076745198b356267bcb95f Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Sun, 7 Jan 2024 20:09:43 -0500 Subject: [PATCH 10/12] fix menu --- Src/Orbiter/OptionsPages.cpp | 4 ++-- Src/Orbiter/Orbiter.rc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/Orbiter/OptionsPages.cpp b/Src/Orbiter/OptionsPages.cpp index ef75590f4..a5736a3d6 100644 --- a/Src/Orbiter/OptionsPages.cpp +++ b/Src/Orbiter/OptionsPages.cpp @@ -1978,8 +1978,8 @@ const HELPCONTEXT* OptionsPage_Forces::HelpContext() const void OptionsPage_Forces::UpdateControls(HWND hPage) { - std::array residForces = { - IDC_OPT_VEC_WEIGHT, IDC_OPT_VEC_THRUST, IDC_OPT_VEC_LIFT, IDC_OPT_VEC_DRAG, IDC_OPT_VEC_TOTAL, + std::array residForces = { + IDC_OPT_VEC_WEIGHT, IDC_OPT_VEC_THRUST, IDC_OPT_VEC_LIFT, IDC_OPT_VEC_DRAG, IDC_OPT_VEC_SIDEFORCE, IDC_OPT_VEC_TOTAL, IDC_OPT_VEC_TORQUE, IDC_OPT_VEC_LINSCL, IDC_OPT_VEC_LOGSCL, IDC_OPT_VEC_SCALE, IDC_OPT_VEC_OPACITY, IDC_STATIC1, IDC_STATIC2, IDC_STATIC3, IDC_STATIC4, IDC_STATIC5 }; diff --git a/Src/Orbiter/Orbiter.rc b/Src/Orbiter/Orbiter.rc index dfef3646f..ca6293049 100644 --- a/Src/Orbiter/Orbiter.rc +++ b/Src/Orbiter/Orbiter.rc @@ -764,8 +764,8 @@ BEGIN CONTROL "Thrust",IDC_OPT_VEC_THRUST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,40,44,10 CONTROL "Lift",IDC_OPT_VEC_LIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,28,44,10 CONTROL "Drag",IDC_OPT_VEC_DRAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,40,44,10 - CONTROL "Side", IDC_OPT_VEC_SIDEFORCE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 56, 56, 44, 10 - CONTROL "Total",IDC_OPT_VEC_TOTAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,56,80,10 + CONTROL "Side", IDC_OPT_VEC_SIDEFORCE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 56, 52, 44, 10 + CONTROL "Total",IDC_OPT_VEC_TOTAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,68,80,10 GROUPBOX "Angular moments",IDC_STATIC2,6,80,100,26 CONTROL "Torque",IDC_OPT_VEC_TORQUE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,92,80,10 GROUPBOX "Display",IDC_STATIC3,114,16,100,90 From a1bbd0b16b494390342942b39de2fb79d74430e1 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Mon, 8 Jan 2024 11:40:26 +0200 Subject: [PATCH 11/12] - Added rendering of side force vectors --- OVP/D3D7Client/VVessel.cpp | 2 +- OVP/D3D9Client/VVessel.cpp | 10 ++++++++++ Src/Orbiter/Vvessel.cpp | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index d3715168c..84ae613be 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -167,7 +167,7 @@ void vVessel::UpdateRenderVectors() if ((flag & BFV_SIDEFORCE) && vessel->GetSideForceVector(F)) { sprintf(cbuf, "SF = %fN", len = length(F)); if (logscale) len = log(len + shift) - lshift; else len *= scale; - AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0, 0, 1), alpha, D3DRGB(0.0392, 0.6235, 0.4941)); + AddVector(unit(F) * (len * pscale), _V(0, 0, 0), scale2, std::string(cbuf), _V(0.0392, 0.6235, 0.4941), alpha, D3DRGB(0.0392, 0.6235, 0.4941)); } if ((flag & BFV_TOTAL) && vessel->GetForceVector(F)) { sprintf(cbuf, "F = %fN", len = length(F)); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 86dd4c4d4..e4315e328 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -860,6 +860,7 @@ void vVessel::RenderVectors (LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) if (bfvmode & BFV_LIFT) { vessel->GetLiftVector(vector); if (length(vector)>len) len = length(vector); } if (bfvmode & BFV_TOTAL) { vessel->GetForceVector(vector); if (length(vector)>len) len = length(vector); } if (bfvmode & BFV_TORQUE) { vessel->GetTorqueVector(vector); if (length(vector)>len) len = length(vector); } + if (bfvmode & BFV_SIDEFORCE) { vessel->GetSideForceVector(vector); if (length(vector) > len) len = length(vector); } lscale = float(size * sclset / len); } @@ -924,6 +925,15 @@ void vVessel::RenderVectors (LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) RenderAxisLabel(pSkp, ptr(D3DXCOLOR(1,0,1,alpha)), vector, lscale, scale, label, bLog); } } + + if (bfvmode & BFV_SIDEFORCE) { + vessel->GetSideForceVector(vector); + if (length(vector) > threshold) { + RenderAxisVector(pSkp, ptr(D3DXCOLOR(0.0392, 0.6235, 0.4941, alpha)), vector, lscale, scale, bLog); + sprintf_s(label, 64, "SF = %sN", value_string(length(vector))); + RenderAxisLabel(pSkp, ptr(D3DXCOLOR(0.0392, 0.6235, 0.4941, alpha)), vector, lscale, scale, label, bLog); + } + } } } diff --git a/Src/Orbiter/Vvessel.cpp b/Src/Orbiter/Vvessel.cpp index e1c5cbf62..ed81b1dcf 100644 --- a/Src/Orbiter/Vvessel.cpp +++ b/Src/Orbiter/Vvessel.cpp @@ -830,6 +830,11 @@ void VVessel::UpdateRenderVectors() if (logscale) len = log(len+shift) - lshift; else len *= scale; AddVector (F.unit()*(len*pscale), Vector(0,0,0), scale2, std::string(cbuf), Vector (1,1,1), alpha, D3DRGB (1,1,1)); } + if ((flag & BFV_SIDEFORCE) && vessel->GetSideForceVector(F)) { + sprintf(cbuf, "SF =%sN", FloatStr(len = F.length(), 4)); + if (logscale) len = log(len + shift) - lshift; else len *= scale; + AddVector(F.unit() * (len * pscale), Vector(0, 0, 0), scale2, std::string(cbuf), Vector(0.0392, 0.6235, 0.4941), alpha, D3DRGB(0.0392, 0.6235, 0.4941)); + } if (1) { for (int i = 0; i < vessel->nforcevec; i++) { F = vessel->forcevec[i]; From 11f03d34c9aa3763821105362d67b42ddc43eadc Mon Sep 17 00:00:00 2001 From: Matthew W Hume Date: Thu, 11 Jan 2024 23:36:17 -0500 Subject: [PATCH 12/12] fix vector direction display --- Src/Orbiter/Vessel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 74a0eda50..08b9b9146 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -1289,7 +1289,7 @@ bool Vessel::GetSideForceVector (Vector &SF) const } else { double v0 = std::hypot(sp.airvel_ship.x, sp.airvel_ship.z); double scale = (v0 ? SideForce / v0 : 0.0); - SF.Set(0, sp.airvel_ship.z * scale, -sp.airvel_ship.x * scale); + SF.Set(sp.airvel_ship.z * scale, 0, - sp.airvel_ship.x * scale); return true; } }