From b939bb24870cc1811f79534a5cf2fe203ad6a828 Mon Sep 17 00:00:00 2001 From: mschweiger Date: Mon, 31 Oct 2022 21:51:51 +0000 Subject: [PATCH] API: Expose force vector and object axis display options (#287) * #283: Included flags for force vector display options to Graphics API. Extended GetConfigParam to return force vector display parameters. Implemented force vector display in D3D7Client. Still to do: text labels. * #283: D3D7Client: added support for frame axis display for vessels, celestial bodies and surface bases. Cleaned up vector display render pipeline. * #283: Inline client: cleaned up force & axis vector rendering code. * #283: D3D9Client: switched the retrieval of force vector and frame axis display options to the main GraphicsClient interface. Removed the obsolete VisualHelper dialog hooking code from OapiExtensions. --- OVP/D3D7Client/Scene.cpp | 43 ++++ OVP/D3D7Client/Scene.h | 6 + OVP/D3D7Client/VObject.cpp | 177 +++++++++++++++- OVP/D3D7Client/VObject.h | 35 +++- OVP/D3D7Client/VPlanet.cpp | 43 ++-- OVP/D3D7Client/VPlanet.h | 3 + OVP/D3D7Client/VVessel.cpp | 50 +++++ OVP/D3D7Client/VVessel.h | 5 + OVP/D3D9Client/D3D9Client.cpp | 5 +- OVP/D3D9Client/OapiExtension.cpp | 343 ------------------------------- OVP/D3D9Client/OapiExtension.h | 112 ---------- OVP/D3D9Client/Scene.cpp | 6 +- OVP/D3D9Client/VVessel.cpp | 18 +- Orbitersdk/include/GraphicsAPI.h | 68 +++++- Src/Orbiter/Config.cpp | 40 ++-- Src/Orbiter/Config.h | 29 +-- Src/Orbiter/DlgVishelper.cpp | 86 ++++---- Src/Orbiter/Scene.cpp | 51 ++++- Src/Orbiter/Scene.h | 10 +- Src/Orbiter/VBase.cpp | 19 -- Src/Orbiter/VBase.h | 1 - Src/Orbiter/VPlanet.cpp | 34 ++- Src/Orbiter/VPlanet.h | 5 +- Src/Orbiter/Vobject.cpp | 164 +++++++-------- Src/Orbiter/Vobject.h | 47 +++-- Src/Orbiter/Vvessel.cpp | 83 +++----- Src/Orbiter/Vvessel.h | 2 +- 27 files changed, 699 insertions(+), 786 deletions(-) diff --git a/OVP/D3D7Client/Scene.cpp b/OVP/D3D7Client/Scene.cpp index 85b5dee3b..eeb5b491f 100644 --- a/OVP/D3D7Client/Scene.cpp +++ b/OVP/D3D7Client/Scene.cpp @@ -539,6 +539,13 @@ void Scene::Render () if (ptex) dev->SetTexture (0, 0); if (!alpha) dev->SetRenderState (D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + // render object vectors + if (*(DWORD*)gc->GetConfigParam(CFGPRM_FORCEVECTORFLAG) & BFV_ENABLE || *(DWORD*)gc->GetConfigParam(CFGPRM_FRAMEAXISFLAG) & FAV_ENABLE) { + cam->SetFrustumLimits(1.0, 1e30); + RenderVectors(); + cam->SetFrustumLimits(npl, fpl); + } + // render the internal parts of the focus object in a separate render pass if (oapiCameraInternal() && vFocus) { // switch cockpit lights on, external-only lights off @@ -632,6 +639,42 @@ void Scene::RenderObjectMarker (oapi::Sketchpad* pSkp, const VECTOR3 &gpos, cons m_celSphere->RenderMarker(pSkp, dp, label1, label2, mode, scale); } +// ============================================================== + +void Scene::RenderVectors() +{ + dev->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + dev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + dev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + dev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + dev->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, TRUE); + dev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); + dev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_POINT); + dev->SetTexture(0, 0); + D3DMATERIAL7 pmtrl, mtrl = { {1,1,1,1},{1,1,1,1},{1,1,1,1},{0.2,0.2,0.2,1},40 }; + dev->GetMaterial(&pmtrl); + dev->SetMaterial(&mtrl); + + for (VOBJREC* pv = vobjFirst; pv; pv = pv->next) { + pv->vobj->RenderVectors(dev); + } + + dev->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); + dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + dev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + dev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + dev->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE); + dev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + dev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR); + dev->SetMaterial(&pmtrl); +} + +// ============================================================== + void Scene::NewVessel (OBJHANDLE hVessel) { CheckVisual (hVessel); diff --git a/OVP/D3D7Client/Scene.h b/OVP/D3D7Client/Scene.h index ab854506d..5e4f1e5d8 100644 --- a/OVP/D3D7Client/Scene.h +++ b/OVP/D3D7Client/Scene.h @@ -108,6 +108,12 @@ class Scene { */ void RenderObjectMarker (oapi::Sketchpad* pSkp, const VECTOR3 &gpos, const std::string& label1, const std::string& label2, int mode, int scale); + /** + * \brief Render vector features for each visual object if requested + * (frame axes, force vectors, etc.) + */ + void RenderVectors(); + void AddLocalLight (const LightEmitter *le, const vObject *vo, DWORD idx); private: diff --git a/OVP/D3D7Client/VObject.cpp b/OVP/D3D7Client/VObject.cpp index a4254f360..ffcec4e89 100644 --- a/OVP/D3D7Client/VObject.cpp +++ b/OVP/D3D7Client/VObject.cpp @@ -30,6 +30,7 @@ #include "Camera.h" #include "Texture.h" #include "D3D7Util.h" +#include using namespace oapi; @@ -87,6 +88,11 @@ void vObject::Activate (bool isactive) active = isactive; } +bool veccomp(const vObject::BodyVectorRec& v1, const vObject::BodyVectorRec& v2) +{ + return v1.dist > v2.dist; // sort from furthest to nearest +} + bool vObject::Update () { if (!active) return false; @@ -94,8 +100,8 @@ bool vObject::Update () MATRIX3 grot; oapiGetRotationMatrix (hObj, &grot); oapiGetGlobalPos (hObj, &cpos); - cpos -= *scn->GetCamera()->GetGPos(); - // object positions are relative to camera + cpos -= *scn->GetCamera()->GetGPos(); // global object position relative to camera + campos = tmul(grot, -cpos); // camera position in object frame cdist = length (cpos); // camera distance @@ -109,9 +115,39 @@ bool vObject::Update () // update the object's world matrix CheckResolution(); + UpdateRenderVectors(); + std::sort(veclist.begin(), veclist.end(), veccomp); + return true; } +void vObject::UpdateRenderVectors() +{ + veclist.clear(); + + // render object frame axes + DWORD flag = *(DWORD*)gc->GetConfigParam(CFGPRM_FRAMEAXISFLAG); + if (flag & FAV_ENABLE) { + int tp = oapiGetObjectType(hObj); + if ((tp == OBJTP_VESSEL && flag & FAV_VESSEL) || + (tp == OBJTP_PLANET && flag & FAV_CELBODY) || + (tp == OBJTP_SURFBASE && flag & FAV_BASE)) { + + double scale = size * *(float*)gc->GetConfigParam(CFGPRM_FRAMEAXISSCALE); + double rad = size * 0.01; + float alpha = *(float*)gc->GetConfigParam(CFGPRM_FRAMEAXISOPACITY); + AddVector(_V(scale, 0, 0), _V(0, 0, 0), rad, std::string("+x"), _V(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(_V(0, scale, 0), _V(0, 0, 0), rad, std::string("+y"), _V(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(_V(0, 0, scale), _V(0, 0, 0), rad, std::string("+z"), _V(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + if (flag & FAV_NEGATIVE) { + AddVector(_V(-scale, 0, 0), _V(0, 0, 0), rad, std::string("-x"), _V(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(_V(0, -scale, 0), _V(0, 0, 0), rad, std::string("-y"), _V(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(_V(0, 0, -scale), _V(0, 0, 0), rad, std::string("-z"), _V(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + } + } + } +} + void vObject::RenderSpot (LPDIRECT3DDEVICE7 dev, const VECTOR3 *ofs, float size, const VECTOR3 &col, bool lighting, int shape) { static D3DMATRIX W = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1}; @@ -165,3 +201,140 @@ void vObject::RenderSpot (LPDIRECT3DDEVICE7 dev, const VECTOR3 *ofs, float size, dev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); dev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); } + +void vObject::AddVector(const VECTOR3& v, const VECTOR3& orig, double rad, const std::string& label, const VECTOR3& col, float alpha, DWORD lcol, float lsize) +{ + double len = length(v); + if (len < 2.0 * rad) return; // too short to be rendered + + VECTOR3 vu = v / len; + double dist = length(vu - campos); // distance of vector tip from camera + + BodyVectorRec rec; + rec.v = v; + rec.orig = orig; + rec.rad = rad; + rec.dist = dist; + rec.col = col; + rec.alpha = alpha; + rec.label = label; + rec.lcol = lcol; + rec.lsize = lsize; + + veclist.push_back(rec); +} + +void vObject::RenderVectors(LPDIRECT3DDEVICE7 dev) +{ + // Render and texture stage states are assumed to be set correctly on call + + if (veclist.size()) { + float palpha = -1.0f; + VECTOR3 pcol = { -1,-1,-1 }; + for (auto&& vec : veclist) { + if (vec.alpha != palpha || vec.col.x != pcol.x || vec.col.y != pcol.y || vec.col.z != pcol.z) { + dev->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, D3DRGBA(vec.col.x, vec.col.y, vec.col.z, vec.alpha)); + palpha = vec.alpha; pcol = vec.col; + } + if (DrawVector(dev, vec.v, vec.orig, vec.rad) && vec.label.size()) { + double scale3 = (vec.lsize >= 0 ? vec.lsize : size); + //scene->Render3DLabel(mul(body->GRot(), ve->v + ve->v.unit() * (scale3 * 0.1)) + body->GPos(), + // ve->label, scale3, ve->lcol); + } + } + } +} + +bool vObject::DrawVector(LPDIRECT3DDEVICE7 dev, const VECTOR3& end, const VECTOR3& orig, double rad) +{ + static const float EPS = 1e-2f; + static const int nseg = 8; + static const int nVtx = nseg * 5; + static const int nIdx0 = nseg * 6 + nseg * 3; + static const int nIdx1 = nIdx0 + (nseg - 2) * 3; + int i, nIdx; + WORD* Idx; + static D3DVERTEX* Vtx0 = 0, * Vtx = 0; + static WORD* Idx0 = 0, * Idx1 = 0; + if (!Vtx0) { // create vector mesh template (pointing to +y) + int i0, i1; + Vtx0 = new D3DVERTEX[nVtx]; + Vtx = new D3DVERTEX[nVtx]; + Idx0 = new WORD[nIdx0]; + Idx1 = new WORD[nIdx1]; + for (i = 0; i < nseg; i++) { + Vtx0[i + 2 * nseg].x = Vtx0[i + 3 * nseg].x = 2.0f * (Vtx0[i].x = Vtx0[i + nseg].x = Vtx0[i].nx = Vtx0[i + nseg].nx = (float)cos(PI2 * (double)i / (double)nseg)); + Vtx0[i + 2 * nseg].z = Vtx0[i + 3 * nseg].z = 2.0f * (Vtx0[i].z = Vtx0[i + nseg].z = Vtx0[i].nz = Vtx0[i + nseg].nz = (float)sin(PI2 * (double)i / (double)nseg)); + Vtx0[i + 4 * nseg].x = Vtx0[i + 4 * nseg].z = 0.0f; + Vtx0[i].y = 0.0f; Vtx0[i + nseg].y = Vtx0[i + 2 * nseg].y = Vtx0[i + 3 * nseg].y = Vtx0[i + 4 * nseg].y = 1.0f; + Vtx0[i + 3 * nseg].nx = Vtx0[i + 4 * nseg].nx = (float)(0.894 * cos(PI2 * (double)(i + 0.5) / (double)nseg)); + Vtx0[i + 3 * nseg].nz = Vtx0[i + 4 * nseg].nz = (float)(0.894 * sin(PI2 * (double)(i + 0.5) / (double)nseg)); + Vtx0[i + 3 * nseg].ny = Vtx0[i + 4 * nseg].ny = 0.447f; + Vtx0[i].ny = Vtx0[i + nseg].ny = Vtx0[i + 2 * nseg].nx = Vtx0[i + 2 * nseg].nz = 0.0f; + Vtx0[i + 2 * nseg].ny = -1.0f; + } + for (i = i0 = 0, i1 = 6 * (nseg - 1); i < nseg; i++) { // stem + Idx0[i0++] = Idx1[i1++] = (WORD)i; + Idx0[i0++] = Idx1[i1++] = (WORD)(i + nseg); + Idx0[i0++] = Idx1[i1++] = (WORD)((i + 1) % nseg + nseg); + Idx0[i0++] = Idx1[i1++] = (WORD)i; + Idx0[i0++] = Idx1[i1++] = (WORD)((i + 1) % nseg + nseg); + Idx0[i0++] = Idx1[i1++] = (WORD)((i + 1) % nseg); + } + for (i = 0, i1 = nseg * 3; i < nseg - 2; i++) { // tip base + Idx1[i1++] = nseg * 2; + Idx1[i1++] = nseg * 2 + 1 + i; + Idx1[i1++] = nseg * 2 + 2 + i; + } + for (i = i1 = 0, i0 = nseg * 6; i < nseg; i++) { // tip + Idx0[i0++] = Idx1[i1++] = nseg * 3 + i; + Idx0[i0++] = Idx1[i1++] = nseg * 4 + i; + Idx0[i0++] = Idx1[i1++] = 3 * nseg + (i + 1) % nseg; + } + } + + float w = (float)rad; + float h = (float)length(end); + if (h < EPS) return false; + float hb = max(h - 4.0f * w, 0); + + memcpy(Vtx, Vtx0, nVtx * sizeof(D3DVERTEX)); + + for (i = 0; i < nseg; i++) { + Vtx[i + 3 * nseg].y = Vtx[i + 2 * nseg].y = Vtx[i + nseg].y = hb; + Vtx[i + 4 * nseg].y = h; + Vtx[i].x = Vtx[i + nseg].x *= w, Vtx[i].z = Vtx[i + nseg].z *= w; + Vtx[i + 3 * nseg].x = Vtx[i + 2 * nseg].x *= w, Vtx[i + 3 * nseg].z = Vtx[i + 2 * nseg].z *= w; + } + + // rotate vector + VECTOR3 d = end / h; + double tht = acos(d.y), phi = atan2(d.z, d.x); + float cost = (float)cos(tht), sint = (float)sin(tht); + float cosp = (float)cos(phi), sinp = (float)sin(phi); + D3DMATRIX W, R = { cost * cosp, -sint, cost * sinp, 0, + sint * cosp, cost, sint * sinp, 0, + -sinp, 0 , cosp, 0, + 0, 0, 0, 1 }; + + // shift vector + R._41 = (float)orig.x; + R._42 = (float)orig.y; + R._43 = (float)orig.z; + D3DMAT_MatrixMultiply(&W, &mWorld, &R); + dev->SetTransform(D3DTRANSFORMSTATE_WORLD, &W); + + MATRIX3 grot; + VECTOR3 gpos; + oapiGetRotationMatrix(hObj, &grot); + VECTOR3 cp = tmul(grot, -cpos); + if (dotp(d, unit(end - cp)) > 0) + Idx = Idx1, nIdx = nIdx1; + else + Idx = Idx0, nIdx = nIdx0; + + dev->DrawIndexedPrimitive( + D3DPT_TRIANGLELIST, D3DFVF_VERTEX, Vtx, nVtx, Idx, nIdx, 0); + dev->SetTransform(D3DTRANSFORMSTATE_WORLD, &mWorld); + return true; +} diff --git a/OVP/D3D7Client/VObject.h b/OVP/D3D7Client/VObject.h index 9f7796588..8ea042b14 100644 --- a/OVP/D3D7Client/VObject.h +++ b/OVP/D3D7Client/VObject.h @@ -140,6 +140,16 @@ class vObject: public oapi::VisObject { */ virtual bool Update (); + /** + * \brief Set up any vectors (forces, coordinate axes) to be drawn in the + * next render pass. + * + * Resets the vector list and adds object frame axes if requested for the + * given object type. Derived classes should extend this to add their own + * vector displays. + */ + virtual void UpdateRenderVectors(); + /** * \brief Level-of-detail check * \default None. @@ -167,9 +177,30 @@ class vObject: public oapi::VisObject { */ virtual void RenderBeacons (LPDIRECT3DDEVICE7 dev) {} + /** + * \brief structure for rendering vectors + */ + struct BodyVectorRec { + VECTOR3 v; ///< vector definition in local object frame + VECTOR3 orig; ///< vector origin in local object frame + double rad; ///< vector arrow radius + double dist; ///< camera distance + VECTOR3 col; ///< colour components + float alpha; ///< alpha component + std::string label; ///< vector label + DWORD lcol; + float lsize; ///< length scale + }; + + virtual void RenderVectors(LPDIRECT3DDEVICE7 dev); + protected: void RenderSpot (LPDIRECT3DDEVICE7 dev, const VECTOR3 *ofs, float size, const VECTOR3 &col, bool lighting, int shape); + void AddVector(const VECTOR3& v, const VECTOR3& orig, double rad, const std::string& label, const VECTOR3& col, float alpha = 1.0f, DWORD lcol = 0, float lsize = -1.0); + + bool DrawVector(LPDIRECT3DDEVICE7 dev, const VECTOR3& end, const VECTOR3& orig, double rad); + static const oapi::D3D7Client *gc; // graphics client instance pointer static LPDIRECTDRAWSURFACE7 blobtex[3]; // beacon textures @@ -180,7 +211,9 @@ class vObject: public oapi::VisObject { MATRIX4 dmWorld; // world matrix in double precision double size; // object radius [m] double cdist; // current camera distance - VECTOR3 cpos; // camera-relative object position + VECTOR3 cpos; // camera-relative object position in global frame + VECTOR3 campos; // camera position in object frame + std::vector veclist; ///< list of body vectors to be rendered }; #endif // !__VOBJECT_H \ No newline at end of file diff --git a/OVP/D3D7Client/VPlanet.cpp b/OVP/D3D7Client/VPlanet.cpp index fbf8ede22..6a8c88c9b 100644 --- a/OVP/D3D7Client/VPlanet.cpp +++ b/OVP/D3D7Client/VPlanet.cpp @@ -193,17 +193,19 @@ bool vPlanet::Update () // rescale = true; // dist_scale = (FLOAT)(farplane/(cdist+render_rad)); //} + mWorldScaled = mWorld; + if (rescale) { rad_scale *= dist_scale; - mWorld._41 *= dist_scale; - mWorld._42 *= dist_scale; - mWorld._43 *= dist_scale; + mWorldScaled._41 *= dist_scale; + mWorldScaled._42 *= dist_scale; + mWorldScaled._43 *= dist_scale; } // scale up from template sphere radius 1 - mWorld._11 *= rad_scale; mWorld._12 *= rad_scale; mWorld._13 *= rad_scale; - mWorld._21 *= rad_scale; mWorld._22 *= rad_scale; mWorld._23 *= rad_scale; - mWorld._31 *= rad_scale; mWorld._32 *= rad_scale; mWorld._33 *= rad_scale; + mWorldScaled._11 *= rad_scale; mWorldScaled._12 *= rad_scale; mWorldScaled._13 *= rad_scale; + mWorldScaled._21 *= rad_scale; mWorldScaled._22 *= rad_scale; mWorldScaled._23 *= rad_scale; + mWorldScaled._31 *= rad_scale; mWorldScaled._32 *= rad_scale; mWorldScaled._33 *= rad_scale; // cloud layer world matrix if (prm.bCloud) { @@ -224,7 +226,7 @@ bool vPlanet::Update () float cloudscale = (float)(cloudrad/size); // world matrix for cloud shadows on the surface - memcpy (&clouddata->mWorldC0, &mWorld, sizeof (D3DMATRIX)); + memcpy (&clouddata->mWorldC0, &mWorldScaled, sizeof (D3DMATRIX)); if (prm.cloudrot) { static D3DMATRIX crot (1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); crot._11 = crot._33 = (float)cos(prm.cloudrot); @@ -355,7 +357,7 @@ bool vPlanet::Render (LPDIRECT3DDEVICE7 dev) if (ringmgr) { if (cdist < rad*ringmgr->InnerRad()) { // camera inside inner ring edge - ringmgr->Render (dev, mWorld); + ringmgr->Render (dev, mWorldScaled); } else { // if the planet has a ring system we update the z-buffer // but don't do z-checking for the planet surface @@ -369,7 +371,7 @@ bool vPlanet::Render (LPDIRECT3DDEVICE7 dev) } if (prm.bCloud && (prm.cloudvis & 1)) RenderCloudLayer (dev, D3DCULL_CW, prm); // render clouds from below - if (hazemgr) hazemgr->Render (dev, mWorld); // horizon ring + if (hazemgr) hazemgr->Render (dev, mWorldScaled); // horizon ring if (prm.bAtm) { if (ModLighting (amb)) @@ -433,7 +435,7 @@ bool vPlanet::Render (LPDIRECT3DDEVICE7 dev) } if (mesh) { - dev->SetTransform (D3DTRANSFORMSTATE_WORLD, &mWorld); + dev->SetTransform (D3DTRANSFORMSTATE_WORLD, &mWorldScaled); mesh->Render (dev); } else { bool using_zbuf; @@ -460,11 +462,11 @@ bool vPlanet::Render (LPDIRECT3DDEVICE7 dev) } if (prm.bCloud && (prm.cloudvis & 2)) RenderCloudLayer (dev, D3DCULL_CCW, prm); // render clouds from above - if (hazemgr) hazemgr->Render (dev, mWorld, true); // haze across planet disc + if (hazemgr) hazemgr->Render (dev, mWorldScaled, true); // haze across planet disc if (ringpostrender) { // turn z-buffer on for ring system dev->SetRenderState (D3DRENDERSTATE_ZENABLE, TRUE); - ringmgr->Render (dev, mWorld); + ringmgr->Render (dev, mWorldScaled); dev->SetRenderState (D3DRENDERSTATE_ZENABLE, FALSE); dev->SetRenderState (D3DRENDERSTATE_ZWRITEENABLE, FALSE); } @@ -540,7 +542,7 @@ void vPlanet::RenderSphere (LPDIRECT3DDEVICE7 dev, const RenderPrm &prm, bool &u using_zbuf = true; } } else { - surfmgr->Render (dev, mWorld, dist_scale, patchres, 0.0, prm.bFog); // surface + surfmgr->Render (dev, mWorldScaled, dist_scale, patchres, 0.0, prm.bFog); // surface } if (prm.bAddBkg) { @@ -585,6 +587,21 @@ void vPlanet::RenderCloudLayer (LPDIRECT3DDEVICE7 dev, DWORD cullmode, const Ren if (cullmode != D3DCULL_CCW) dev->SetRenderState (D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); } +void vPlanet::RenderVectors(LPDIRECT3DDEVICE7 dev) +{ + vObject::RenderVectors(dev); + RenderBaseVectors(dev); +} + +// ============================================================== + +void vPlanet::RenderBaseVectors(LPDIRECT3DDEVICE7 dev) +{ + for (DWORD i = 0; i < nbase; i++) + if (vbase[i]) + vbase[i]->RenderVectors(dev); +} + // ============================================================== void vPlanet::RenderCloudShadows (LPDIRECT3DDEVICE7 dev, const RenderPrm &prm) diff --git a/OVP/D3D7Client/VPlanet.h b/OVP/D3D7Client/VPlanet.h index 0011fa408..1fa9815bc 100644 --- a/OVP/D3D7Client/VPlanet.h +++ b/OVP/D3D7Client/VPlanet.h @@ -80,6 +80,8 @@ class vPlanet: public vObject { void RenderDot (LPDIRECT3DDEVICE7 dev); void RenderSphere (LPDIRECT3DDEVICE7 dev, const RenderPrm &prm, bool &using_zbuf); void RenderCloudLayer (LPDIRECT3DDEVICE7 dev, DWORD cullmode, const RenderPrm &prm); + void RenderVectors(LPDIRECT3DDEVICE7 dev); + void RenderBaseVectors(LPDIRECT3DDEVICE7 dev); void RenderBaseSurfaces (LPDIRECT3DDEVICE7 dev); void RenderBaseStructures (LPDIRECT3DDEVICE7 dev); void RenderBaseShadows (LPDIRECT3DDEVICE7 dev, float depth); @@ -110,6 +112,7 @@ class vPlanet: public vObject { bool bVesselShadow; // render vessel shadows on surface FogParam fog; // distance fog render parameters D3D7Mesh *mesh; // mesh for nonspherical body + D3DMATRIX mWorldScaled; // rescaled world matrix struct CloudData { // cloud render parameters (for legacy interface) CloudManager *cloudmgr; // cloud tile manager diff --git a/OVP/D3D7Client/VVessel.cpp b/OVP/D3D7Client/VVessel.cpp index eec2c19c9..4fdfd079c 100644 --- a/OVP/D3D7Client/VVessel.cpp +++ b/OVP/D3D7Client/VVessel.cpp @@ -124,6 +124,56 @@ bool vVessel::Update () return true; } +void vVessel::UpdateRenderVectors() +{ + vObject::UpdateRenderVectors(); + + DWORD flag = *(DWORD*)gc->GetConfigParam(CFGPRM_FORCEVECTORFLAG); + if (flag & BFV_ENABLE) { + VESSEL* vessel = oapiGetVesselInterface(hObj); + static double shift = 1e3, lshift = log(shift); + bool logscale = ((flag & BFV_LOGSCALE) != 0); + double len, scale, scale2 = size * 0.02; + scale = (logscale ? 1.0 : size / (vessel->GetMass() * 9.81)); + double m = vessel->GetMass(); // DEBUG + double pscale = *(float*)gc->GetConfigParam(CFGPRM_FORCEVECTORSCALE); + float alpha = *(float*)gc->GetConfigParam(CFGPRM_FORCEVECTOROPACITY); + char cbuf[256]; + VECTOR3 F; + + if ((flag & BFV_WEIGHT) && vessel->GetWeightVector(F)) { + sprintf(cbuf, "G = %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(1, 1, 0), alpha, D3DRGB(1, 1, 0)); + } + if ((flag & BFV_THRUST) && vessel->GetThrustVector(F)) { + sprintf(cbuf, "T = %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.5, 1)); + } + if ((flag & BFV_LIFT) && vessel->GetLiftVector(F)) { + sprintf(cbuf, "L = %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, 1, 0), alpha, D3DRGB(0.5, 1, 0.5)); + } + if ((flag & BFV_DRAG) && vessel->GetDragVector(F)) { + sprintf(cbuf, "D = %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(1, 0, 0), alpha, D3DRGB(1, 0.5, 0.5)); + } + if ((flag & BFV_TOTAL) && vessel->GetForceVector(F)) { + sprintf(cbuf, "F = %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(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + } + if ((flag & BFV_TORQUE) && vessel->GetTorqueVector(F)) { + sprintf(cbuf, "M = %fNm", len = length(F)); + 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)); + } + } +} + void vVessel::LoadMeshes () { if (nmesh) ClearMeshes(); diff --git a/OVP/D3D7Client/VVessel.h b/OVP/D3D7Client/VVessel.h index ae2a135b2..82a335f59 100644 --- a/OVP/D3D7Client/VVessel.h +++ b/OVP/D3D7Client/VVessel.h @@ -61,6 +61,11 @@ class vVessel: public vObject { */ bool Update (); + /** + * \brief Set up the vessel vectors (forces, frame axes) to render + */ + void UpdateRenderVectors(); + /** * \brief Object render call * \param dev render device diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index f707f1e00..bbf8c1196 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -283,7 +283,7 @@ bool D3D9Client::ChkDev(const char *fnc) const // const void *D3D9Client::GetConfigParam (DWORD paramtype) const { - return (paramtype >= CFGPRM_SHOWBODYFORCEVECTORSFLAG) + return (paramtype >= CFGPRM_TILELOADTHREAD) ? (paramtype >= CFGPRM_GETSELECTEDMESH) ? DebugControls::GetConfigParam(paramtype) : OapiExtension::GetConfigParam(paramtype) @@ -1273,9 +1273,6 @@ bool D3D9Client::RenderWithPopupWindows() else GetDevice()->SetDialogBoxMode(false); } - // Let the OapiExtension manager know about this.. - OapiExtension::HandlePopupWindows(hPopupWnd, count); - FixOutOfScreenPositions(hPopupWnd, count); if (!bFullscreen) { diff --git a/OVP/D3D9Client/OapiExtension.cpp b/OVP/D3D9Client/OapiExtension.cpp index 2d08b653c..f6ea3ff32 100644 --- a/OVP/D3D9Client/OapiExtension.cpp +++ b/OVP/D3D9Client/OapiExtension.cpp @@ -12,44 +12,11 @@ #include "OrbiterAPI.h" #include -// =========================================================================== -// Orbiter [v110830] up to [v111105] up to [v221025] -#define IDC_BODYFORCE_PAGE 233 -#define IDC_BODYFORCE_ENABLE 1819 -#define IDC_BODYFORCE_WEIGHT 1820 -#define IDC_BODYFORCE_THRUST 1821 -#define IDC_BODYFORCE_LIFT 1822 -#define IDC_BODYFORCE_DRAG 1823 -#define IDC_BODYFORCE_TOTAL 1824 -#define IDC_BODYFORCE_TORQUE 1825 -#define IDC_BODYFORCE_SCALE_LIN 1826 -#define IDC_BODYFORCE_SCALE_LOG 1827 -#define IDC_BODYFORCE_SCALE_GAUGE 1828 -#define IDC_BODYFORCE_OPACITY_GAUGE 1829 - -#define IDC_SHOW_AXES_PAGE 234 -#define IDC_SHOW_AXES_ENABLE 1830 -#define IDC_SHOW_AXES_VESSEL 1831 -#define IDC_SHOW_AXES_CELBODY 1832 -#define IDC_SHOW_AXES_SURFBASE 1833 -#define IDC_SHOW_AXES_NEGATIVE 1834 -#define IDC_SHOW_AXES_SCALE_GAUGE 1835 -#define IDC_SHOW_AXES_OPACITY_GAUGE 1836 - -// Little binary helper -#define SETFLAG(bitmap, bit, value) (value ? bitmap |= bit : bitmap &= ~bit) // =========================================================================== // Class statics initialization DWORD OapiExtension::elevationMode = 0; -DWORD OapiExtension::showBodyForceVectorsFlags = (BFV_WEIGHT | BFV_THRUST | BFV_LIFT | BFV_DRAG); -float OapiExtension::bodyForceScale = 1.0; -float OapiExtension::bodyForceOpacity = 1.0; -// Orbiters default here: "CoordinateAxes = 4 1 1" -DWORD OapiExtension::showCoordinateAxesFlags = SCA_VESSEL; -float OapiExtension::coordinateAxesScale = 1.0; -float OapiExtension::coordinateAxesOpacity = 1.0; // Orbiters default directories std::string OapiExtension::configDir(".\\Config\\"); std::string OapiExtension::meshDir(".\\Meshes\\"); @@ -72,27 +39,6 @@ bool OapiExtension::tileLoadThread = true; bool OapiExtension::runsUnderWINE = false; bool OapiExtension::runsSpacecraftDll = false; -// hooking -DWORD OapiExtension::hookMap = 0L; -HOOKINFO OapiExtension::hookInfos[] = { - // idc , hookFlag , lpWrapWndFunc - {IDC_BODYFORCE_ENABLE , BFV_ENABLE , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_WEIGHT , BFV_WEIGHT , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_THRUST , BFV_THRUST , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_LIFT , BFV_LIFT , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_DRAG , BFV_DRAG , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_TOTAL , BFV_TOTAL , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_TORQUE , BFV_TORQUE , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_SCALE_LOG , BFV_SCALE_LOG, (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_SHOW_AXES_ENABLE , SCA_ENABLE , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_SHOW_AXES_VESSEL , SCA_VESSEL , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_SHOW_AXES_CELBODY , SCA_CELBODY , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_SHOW_AXES_SURFBASE , SCA_SURFBASE , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_SHOW_AXES_NEGATIVE , SCA_NEGATIVE , (WNDPROC)CheckBoxWindowProc, NULL, NULL, NULL, NULL}, - {IDC_BODYFORCE_PAGE , 0x02000 , (WNDPROC)GaugeWindowProc , NULL, NULL, NULL, NULL}, - {IDC_SHOW_AXES_PAGE , 0x04000 , (WNDPROC)GaugeWindowProc , NULL, NULL, NULL, NULL} - // Sum: 0x07FFF (SCA_xxx hookFlag values are shifted! (<<8) ) -}; // =========================================================================== // Construction @@ -105,10 +51,6 @@ OapiExtension::OapiExtension(void) { // OapiExtension::~OapiExtension(void) { - // Unhook still hooked methods, should not happen - for (int i=0; i < sizeof(hookInfos)/sizeof(HOOKINFO); ++i) { - RemoveHook(&hookInfos[i]); - } } @@ -123,9 +65,6 @@ OapiExtension::~OapiExtension(void) // void OapiExtension::GlobalInit(const D3D9Config &Config) { - if (Config.DisableVisualHelperReadout) { - hookMap = 0x7FFF; // pretend all hooks are already set - } } // =========================================================================== @@ -136,35 +75,11 @@ const void *OapiExtension::GetConfigParam (DWORD paramtype) { switch (paramtype) { case CFGPRM_ELEVATIONINTERPOLATION : return (void*)&elevationMode; - case CFGPRM_SHOWBODYFORCEVECTORSFLAG: return (void*)&showBodyForceVectorsFlags; - case CFGPRM_BODYFORCEVECTORSSCALE : return (void*)&bodyForceScale; - case CFGPRM_BODYFORCEVECTORSOPACITY : return (void*)&bodyForceOpacity; - case CFGPRM_SHOWCOORDINATEAXESFLAG : return (void*)&showCoordinateAxesFlags; - case CFGPRM_COORDINATEAXESSCALE : return (void*)&coordinateAxesScale; - case CFGPRM_COORDINATEAXESOPACITY : return (void*)&coordinateAxesOpacity; case CFGPRM_TILELOADTHREAD : return (void*)&tileLoadThread; default : return NULL; } } -// =========================================================================== -// Hooks/Unhooks the popup windows; called whenever popup widows -// appear/disappear -// -void OapiExtension::HandlePopupWindows (const HWND *hPopupWnd, DWORD count) -{ - // New popup window we need to hook onto? - if (count && !AllHooksAttached()) { - for (DWORD i = 0; i < count; ++i) { - if (IsOurDialog(hPopupWnd[i])) { - EnumChildWindows(hPopupWnd[i], EnumChildProc, 0L); - break; - } - } - } -} - - /* ------------------------------------------------------------------------------ PRIVATE METHODS @@ -288,22 +203,6 @@ bool OapiExtension::GetConfigParameter(void) } } - if (oapiReadItem_string(f, "Bodyforces", string)) { - if (3 == sscanf_s(string, "%lu %f %f", &flags, &scale, &opacity)) { - showBodyForceVectorsFlags = flags; - bodyForceScale = scale; - bodyForceOpacity = opacity; - } - } - - if (oapiReadItem_string(f, "CoordinateAxes", string)) { - if (3 == sscanf_s(string, "%lu %f %f", &flags, &scale, &opacity)) { - showCoordinateAxesFlags = flags; - coordinateAxesScale = scale; - coordinateAxesOpacity = opacity; - } - } - // Get planet rendering parameters oapiReadItem_bool(f, "TileLoadThread", tileLoadThread); @@ -399,246 +298,4 @@ std::string OapiExtension::ScanCommandLine (void) return ""; } -// =========================================================================== -// Get pointer to hookInfo structure by control ID -// -const LPHOOKINFO OapiExtension::GetHookInfo(DWORD cid) -{ - for (int i=0; i< sizeof(hookInfos)/sizeof(HOOKINFO); ++i) { - if (hookInfos[i].cid == cid) { - return &hookInfos[i]; - } - } - return NULL; -} - -// =========================================================================== -// Get pointer to hookInfo structure by window handle -// -const LPHOOKINFO OapiExtension::GetHookInfo(HWND hwnd) -{ - for (int i=0; i< sizeof(hookInfos)/sizeof(HOOKINFO); ++i) { - if (hookInfos[i].hWnd == hwnd) { - return &hookInfos[i]; - } - } - return NULL; -} - -// =========================================================================== -// Removes the wrapped window function from the dialog item. -// Note: It does *not* clear the lpOrigWndFunc struct member, 'cause it may -// still be used with a (final) call to CallWindowProc()! -// -const void OapiExtension::RemoveHook(LPHOOKINFO lpHookInfo) -{ - if (lpHookInfo && lpHookInfo->lpOrigWndFunc && lpHookInfo->hWnd) - { - SetWindowLongPtr(lpHookInfo->hWnd, GWLP_WNDPROC, (LONG_PTR)lpHookInfo->lpOrigWndFunc); - lpHookInfo->hWnd = NULL; - lpHookInfo->hWndScaleGauge = NULL; - lpHookInfo->hWndOpacityGauge = NULL; - hookMap &= ~lpHookInfo->hookFlag; - } -} - -// =========================================================================== -// Check helper to avoid hooking 'Orbiter: Configure menu bars' dialog, or -// any other addon-dialog which might use some of the same IDCs as the -// 'Visual helpers' dialog. -// -const bool OapiExtension::IsOurDialog(HWND hwnd) -{ - static char buff[16] = {0}; - return GetWindowText(hwnd, buff, 16) - && !strncmp("Visual helpers", buff, 14); -} - -// =========================================================================== -// Child window enumeration callback (hooks the window message functions) -// -BOOL CALLBACK OapiExtension::EnumChildProc(HWND hwnd, LPARAM lParam) -{ - LPHOOKINFO lpHookInfo; - - int CtrlId = ::GetDlgCtrlID(hwnd); - - switch (CtrlId) { - - // --- Body Forces --- - case IDC_BODYFORCE_ENABLE: - case IDC_BODYFORCE_WEIGHT: - case IDC_BODYFORCE_THRUST: - case IDC_BODYFORCE_LIFT: - case IDC_BODYFORCE_DRAG: - case IDC_BODYFORCE_TOTAL: - case IDC_BODYFORCE_TORQUE: - case IDC_BODYFORCE_SCALE_LOG: - lpHookInfo = GetHookInfo(CtrlId); - SETFLAG(showBodyForceVectorsFlags, lpHookInfo->hookFlag, SendMessage(hwnd, BM_GETCHECK, 0L ,0L)); - lpHookInfo->hWnd = hwnd; - lpHookInfo->lpOrigWndFunc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC); - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)lpHookInfo->lpWrapWndFunc); - hookMap |= lpHookInfo->hookFlag; - break; - - // --- Coordinate Axes --- - case IDC_SHOW_AXES_ENABLE: - case IDC_SHOW_AXES_VESSEL: - case IDC_SHOW_AXES_CELBODY: - case IDC_SHOW_AXES_SURFBASE: - case IDC_SHOW_AXES_NEGATIVE: - lpHookInfo = GetHookInfo(CtrlId); - SETFLAG(showCoordinateAxesFlags, lpHookInfo->hookFlag, SendMessage(hwnd, BM_GETCHECK, 0L ,0L)); - lpHookInfo->hWnd = hwnd; - lpHookInfo->lpOrigWndFunc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC); - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)lpHookInfo->lpWrapWndFunc); - hookMap |= lpHookInfo->hookFlag<<8; - break; - - // --- Gauges (body forces page) --- - case IDC_BODYFORCE_SCALE_GAUGE: - case IDC_BODYFORCE_OPACITY_GAUGE: - lpHookInfo = GetHookInfo(IDC_BODYFORCE_PAGE); - if (!lpHookInfo->hWnd) { - lpHookInfo->hWnd = GetParent(hwnd); - lpHookInfo->lpOrigWndFunc = (WNDPROC)GetWindowLongPtr(GetParent(hwnd), GWLP_WNDPROC); - SetWindowLongPtr(GetParent(hwnd), GWLP_WNDPROC, (LONG_PTR)lpHookInfo->lpWrapWndFunc); - } - - (CtrlId == IDC_BODYFORCE_SCALE_GAUGE) ? lpHookInfo->hWndScaleGauge = hwnd - : lpHookInfo->hWndOpacityGauge = hwnd; - - if (lpHookInfo->hWndScaleGauge && lpHookInfo->hWndOpacityGauge) { - hookMap |= lpHookInfo->hookFlag; - } - break; - - // --- Gauges (coordinate axes page) --- - case IDC_SHOW_AXES_SCALE_GAUGE: - case IDC_SHOW_AXES_OPACITY_GAUGE: - lpHookInfo = GetHookInfo(IDC_SHOW_AXES_PAGE); - if (!lpHookInfo->hWnd) { - lpHookInfo->hWnd = GetParent(hwnd); - lpHookInfo->lpOrigWndFunc = (WNDPROC)GetWindowLongPtr(GetParent(hwnd), GWLP_WNDPROC); - SetWindowLongPtr(GetParent(hwnd), GWLP_WNDPROC, (LONG_PTR)lpHookInfo->lpWrapWndFunc); - } - - (CtrlId == IDC_SHOW_AXES_SCALE_GAUGE) ? lpHookInfo->hWndScaleGauge = hwnd - : lpHookInfo->hWndOpacityGauge = hwnd; - - if (lpHookInfo->hWndScaleGauge && lpHookInfo->hWndOpacityGauge) { - hookMap |= lpHookInfo->hookFlag; - } - break; - - default: - break; - } - return !AllHooksAttached(); -} - -// =========================================================================== -// Checkbox message procedure -// -LRESULT CALLBACK OapiExtension::CheckBoxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - int CtrlId; - LPHOOKINFO lpHookInfo = GetHookInfo(hwnd); - - switch (uMsg) { - - case BM_SETCHECK: - CtrlId = ::GetDlgCtrlID(hwnd); - switch (CtrlId) - { - // --- Body Forces --- - case IDC_BODYFORCE_ENABLE: - case IDC_BODYFORCE_WEIGHT: - case IDC_BODYFORCE_THRUST: - case IDC_BODYFORCE_LIFT: - case IDC_BODYFORCE_DRAG: - case IDC_BODYFORCE_TOTAL: - case IDC_BODYFORCE_TORQUE: - case IDC_BODYFORCE_SCALE_LOG: - SETFLAG(showBodyForceVectorsFlags, lpHookInfo->hookFlag, (wParam == BST_CHECKED)); - break; - // --- Coordinate Axes --- - case IDC_SHOW_AXES_ENABLE: - case IDC_SHOW_AXES_VESSEL: - case IDC_SHOW_AXES_CELBODY: - case IDC_SHOW_AXES_SURFBASE: - case IDC_SHOW_AXES_NEGATIVE: - SETFLAG(showCoordinateAxesFlags, lpHookInfo->hookFlag, (wParam == BST_CHECKED)); - break; - - default: - break; - } - break; - - case WM_DESTROY: - RemoveHook(lpHookInfo); - break; - } - return CallWindowProc(lpHookInfo->lpOrigWndFunc, hwnd, uMsg, wParam, lParam); -} - -// =========================================================================== -// Gauges message procedure (operates on their parent dialog-window) -// -LRESULT CALLBACK OapiExtension::GaugeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - float *pValue; - WORD scrollRequest; - LPHOOKINFO lpHookInfo = GetHookInfo(hwnd); - // --- Scale to Value calculation parameter --- - float vmin(0); // Min value for member value - float vmax(0); // Max value for member value - float step(0); // Step size for SB_LINELEFT, SB_LINERIGHT - bool isScaleGauge(false); // Whether it's a scale-gauge message or a opacity-gauge message - - switch (uMsg) { - - case WM_HSCROLL: - - isScaleGauge = (lpHookInfo->hWndScaleGauge == (HWND)lParam); - - // Select fitting scale 'constants' - vmin = isScaleGauge ? 0.25f : 0.0f; - vmax = isScaleGauge ? 4.0f : 1.0f; - step = (vmax - vmin) / 50.0f; - - // Get pointer to fitting member - if (lpHookInfo->cid == IDC_BODYFORCE_PAGE) { - pValue = isScaleGauge ? &bodyForceScale : &bodyForceOpacity; - } - else if (lpHookInfo->cid == IDC_SHOW_AXES_PAGE) { - pValue = isScaleGauge ? &coordinateAxesScale : &coordinateAxesOpacity; - } - else { - break; // should not happen! - } - - scrollRequest = LOWORD(wParam); - - if (scrollRequest == SB_THUMBTRACK) { - *pValue = (vmax - vmin) * HIWORD(wParam) / 50.0f + vmin; - } - else if (scrollRequest == SB_LINELEFT) { - *pValue = max(vmin, *pValue - step); - } - else if (scrollRequest == SB_LINERIGHT) { - *pValue = min(vmax, *pValue + step); - } - break; - - case WM_DESTROY: - RemoveHook(lpHookInfo); - break; - } - - return CallWindowProc(lpHookInfo->lpOrigWndFunc, hwnd, uMsg, wParam, lParam); -} - // --- eof --- diff --git a/OVP/D3D9Client/OapiExtension.h b/OVP/D3D9Client/OapiExtension.h index 427985f72..1211428da 100644 --- a/OVP/D3D9Client/OapiExtension.h +++ b/OVP/D3D9Client/OapiExtension.h @@ -18,40 +18,6 @@ class D3D9Config; /// Used by OapiExtension::GetConfigParam() /// @{ - -/// Bit flag for "body force vectors display mode" elements. -/// For a description of the available bit flags, see \ref bfvflag -/// \par Parameter type: -/// DWORD -#define CFGPRM_SHOWBODYFORCEVECTORSFLAG 0x1000 - -/// Length factor for body force vectors display (0-1) -/// \par Parameter type: -/// float -#define CFGPRM_BODYFORCEVECTORSSCALE 0x1001 - -/// Opacity of body force vectors (0-1) -/// \par Parameter type: -/// float -#define CFGPRM_BODYFORCEVECTORSOPACITY 0x1002 - -/// Bit flag for "coordinate axes display mode" elements. -/// For a description of the available bit flags, see \ref scaflag -/// \par Parameter type: -/// DWORD -#define CFGPRM_SHOWCOORDINATEAXESFLAG 0x1003 - -/// Length factor for coordinate axes display (0-1) -/// \par Parameter type: -/// float -#define CFGPRM_COORDINATEAXESSCALE 0x1004 - -/// Opacity of coordinate axes (0-1) -/// \par Parameter type: -/// float -#define CFGPRM_COORDINATEAXESOPACITY 0x1005 - - /// Load tiles in separate thread? /// \par Parameter type: /// bool @@ -65,48 +31,6 @@ class D3D9Config; /// @} -/// \defgroup bfvflag Bit flags for body force vector display mode elements -/// @{ -#define BFV_ENABLE 0x0001 ///< Enable body force vectors display mode (master flag) -#define BFV_SCALE_LOG 0x0002 ///< Flag indicating logarithmic (1) or linear (0) scale is used for displaying vector lengths -#define BFV_WEIGHT 0x0004 ///< Enable weight force vector display -#define BFV_THRUST 0x0008 ///< Enable thrust force vector display -#define BFV_LIFT 0x0010 ///< Enable lift force vector display -#define BFV_DRAG 0x0020 ///< Enable drag force vector display -#define BFV_TOTAL 0x0040 ///< Enable total force vector display -#define BFV_TORQUE 0x0080 ///< Enable torque force vector display - -/// @} - - -/// \defgroup scaflag Bit flags for coordinate axes vector display mode elements -/// @{ -#define SCA_ENABLE 0x0001 ///< Enable coordinate axes display mode (master flag) -#define SCA_NEGATIVE 0x0002 ///< Enable display of negative axes -#define SCA_VESSEL 0x0004 ///< Enable vessel coordinate axes -#define SCA_CELBODY 0x0008 ///< Enable celestial body coordinate axes -#define SCA_SURFBASE 0x0010 ///< Enable surface base coordinate axes - -/// @} - - -/** - * \brief Storage structure to keep hooking information. - * - * This struct basically keeps track of whether a hook is installed or not and - * stores the original handles for later recovery. - */ -typedef struct { - int cid; ///< ControlID (IDC_xxx) - DWORD hookFlag; ///< Bit flag for the hookMap - WNDPROC lpWrapWndFunc; ///< Wrapped WindowProc - WNDPROC lpOrigWndFunc; ///< Original WindowProc - HWND hWnd; ///< Window (e.g. CheckBox) handle - HWND hWndScaleGauge; ///< Scale gauge handle - HWND hWndOpacityGauge; ///< Opacity gauge handle -} HOOKINFO, *LPHOOKINFO; - - /** * \brief Configuration parameter provider for non-API parameters * @@ -129,20 +53,6 @@ class OapiExtension */ static void GlobalInit(const D3D9Config &Config); - /** - * \brief Handles the read-out of values from an opened 'visual helpers' - * dialog. - * - * This function handles the attachment of delegate functions to the popup - * windows. It has to be called whenever popup widows appears/disappears - * \param hPopupWnd The list returned by the \ref - * oapi::GraphicsClient::GetPopupList method, containing the handles of - * popup windows that are to be rendered. - * \param count Number of entries in the list (return value of \ref - * oapi::GraphicsClient::GetPopupList. - */ - static void HandlePopupWindows (const HWND *hPopupWnd, DWORD count); - /** * \brief Same functionality than 'official' GetConfigParam, but for * non-provided config parameters @@ -241,14 +151,6 @@ class OapiExtension // Planet rendering parameters static DWORD elevationMode; static bool tileLoadThread; ///< Whether to load planet tiles in separate thread [true|false] - // Body forces - static DWORD showBodyForceVectorsFlags; - static float bodyForceScale; // [0.25..4.0] - static float bodyForceOpacity; // [0...1] - // Coordinate axes - static DWORD showCoordinateAxesFlags; - static float coordinateAxesScale; // [0.25...4.0] - static float coordinateAxesOpacity; // [0...1] // OrbiterSound 4.0 helper static bool isOrbiter2010; ///< Whether we run Orbiter 2010 (and derivatives) static bool orbiterSound40; @@ -264,23 +166,9 @@ class OapiExtension static bool runsSpacecraftDll; ///< Whether the current Scenario uses Spacecraft.dll static void LogD3D9Modules(void); ///< Logs loaded D3D9 DLLs and their versions - // Hooking - static DWORD hookMap; // Flags indicating 'already delegated' widgets - static HOOKINFO hookInfos[]; // Table of information of wrapped methods and items - static bool configParameterRead; ///< Indication that Orbiter_NG.cfg has been read static bool GetConfigParameter(void); ///< Tries to read parameter from Orbiter_NG.cfg static std::string ScanCommandLine(void); ///< Tries to read a Startup Scenario given by "-s" command line parameter - - static bool AllHooksAttached(void) {return hookMap == 0x7FFF;} - static const LPHOOKINFO GetHookInfo(DWORD cid); - static const LPHOOKINFO GetHookInfo(HWND hwnd); - static const void RemoveHook(LPHOOKINFO lpHookInfo); - - static const bool IsOurDialog(HWND hwnd); - static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam); - static LRESULT CALLBACK CheckBoxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK GaugeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; #endif // !__OAPIEXTENSION_H diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 61b3069ea..48cfd9ab2 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1653,10 +1653,10 @@ void Scene::RenderMainScene() // Render vessel axis vectors // ------------------------------------------------------------------------------------------------------- - DWORD bfvmode = *(DWORD*)gc->GetConfigParam(CFGPRM_SHOWBODYFORCEVECTORSFLAG); - DWORD scamode = *(DWORD*)gc->GetConfigParam(CFGPRM_SHOWCOORDINATEAXESFLAG); + DWORD bfvmode = *(DWORD*)gc->GetConfigParam(CFGPRM_FORCEVECTORFLAG); + DWORD scamode = *(DWORD*)gc->GetConfigParam(CFGPRM_FRAMEAXISFLAG); - if (bfvmode&BFV_ENABLE || scamode&SCA_ENABLE) + if (bfvmode & BFV_ENABLE || scamode & FAV_ENABLE) { pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0L); // clear z-buffer diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index aad1441d8..d960e37ef 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -825,8 +825,8 @@ void vVessel::RenderAxis(LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) float alpha; double len = 1e-9f; // avoids division by zero if len is not updated - DWORD bfvmode = *(DWORD*)gc->GetConfigParam(CFGPRM_SHOWBODYFORCEVECTORSFLAG); - float sclset = *(float*)gc->GetConfigParam(CFGPRM_BODYFORCEVECTORSSCALE); + DWORD bfvmode = *(DWORD*)gc->GetConfigParam(CFGPRM_FORCEVECTORFLAG); + float sclset = *(float*)gc->GetConfigParam(CFGPRM_FORCEVECTORSCALE); float scale = float(size) / 50.0f; // ------------------------------------- @@ -837,7 +837,7 @@ void vVessel::RenderAxis(LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) char label[64]; bool bLog; - if (bfvmode & BFV_SCALE_LOG) bLog = true; + if (bfvmode & BFV_LOGSCALE) bLog = true; else bLog = false; if (!bLog) { @@ -854,7 +854,7 @@ void vVessel::RenderAxis(LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) lscale = float(size * sclset / 50.0); } - alpha = *(float*)gc->GetConfigParam(CFGPRM_BODYFORCEVECTORSOPACITY); + alpha = *(float*)gc->GetConfigParam(CFGPRM_FORCEVECTOROPACITY); if (alpha > 1e-9) // skip all this when opacity is to small (ZEROish) { @@ -917,15 +917,15 @@ void vVessel::RenderAxis(LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) // ------------------------------------- // Render Axes - DWORD scamode = *(DWORD*)gc->GetConfigParam(CFGPRM_SHOWCOORDINATEAXESFLAG); + DWORD scamode = *(DWORD*)gc->GetConfigParam(CFGPRM_FRAMEAXISFLAG); - if (scamode&SCA_ENABLE && scamode&SCA_VESSEL) + if (scamode & FAV_ENABLE && scamode & FAV_VESSEL) { - float alpha = *(float*)gc->GetConfigParam(CFGPRM_COORDINATEAXESOPACITY); + float alpha = *(float*)gc->GetConfigParam(CFGPRM_FRAMEAXISOPACITY); if (alpha > 1e-9) // skip all this when opacity is to small (ZEROish) { - float sclset = *(float*)gc->GetConfigParam(CFGPRM_COORDINATEAXESSCALE); + float sclset = *(float*)gc->GetConfigParam(CFGPRM_FRAMEAXISSCALE); scale *= 0.99f; // 1% "slimmer" to avoid z-fighting with force vector(s) float ascale = float(size)*sclset*0.5f; @@ -938,7 +938,7 @@ void vVessel::RenderAxis(LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) RenderAxisVector(pSkp, &D3DXCOLOR(0,0,1,alpha), _V(0,0,1), ascale, scale); RenderAxisLabel(pSkp, &D3DXCOLOR(0,0,1,alpha), _V(0,0,1), ascale, scale, "Z"); - if (scamode&SCA_NEGATIVE) { + if (scamode & FAV_NEGATIVE) { RenderAxisVector(pSkp, &D3DXCOLOR(1,0,0,alpha*0.5f), _V(-1,0,0), ascale, scale); RenderAxisLabel(pSkp, &D3DXCOLOR(1,0,0,alpha), _V(-1,0,0), ascale, scale, "-X"); diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 81dec471e..6be31b06c 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -180,13 +180,58 @@ typedef void *HDC; */ #define CFGPRM_TILEPATCHRES 0x001B -#define CFGPRM_TILELOADFLAGS 0x001C /** * Bitflags for planetary tile file load behaviour * - bit 1: load from individual tiles in directory tree * - bit 2: load from compressed archive file * \par Parameter type: * DWORD + */ +#define CFGPRM_TILELOADFLAGS 0x001C + +/** + * Bit flags for force vector display options. + * For a description of the available bit flags, see \ref bfvflag + * \par Parameter type: + * DWORD + */ +#define CFGPRM_FORCEVECTORFLAG 0x001D + +/** + * Force vector display scaling factor + * \par Parameter type: + * float + */ +#define CFGPRM_FORCEVECTORSCALE 0x001E + +/** + * Force vector display opacity value + * \par Parameter type: + * float + */ +#define CFGPRM_FORCEVECTOROPACITY 0x001F + +/** + * Bit flags for frame axis display options. + * For a description of the available bit flags, see \ref favflag + * \par Parameter type: + * DWORD + */ +#define CFGPRM_FRAMEAXISFLAG 0x0020 + +/** + * Frame axis display scaling factor + * \par Parameter type: + * float + */ +#define CFGPRM_FRAMEAXISSCALE 0x0021 + +/** + * Frame axis display opacity value + * \par Parameter type: + * float + */ +#define CFGPRM_FRAMEAXISOPACITY 0x0022 /// @} /** @@ -222,6 +267,27 @@ typedef void *HDC; #define PLN_SURFMARK (PLN_BMARK | PLN_RMARK | PLN_LMARK) /// @} +/// \defgroup bfvflag Bit flags for vessel force vector render options +/// @{ +#define BFV_ENABLE 0x0001 ///< Enable body force vectors +#define BFV_LOGSCALE 0x0002 ///< Use logarithmic scale (instead of linear scale) +#define BFV_WEIGHT 0x0004 ///< Show weight vector +#define BFV_THRUST 0x0008 ///< Show thrust vector +#define BFV_LIFT 0x0010 ///< Show lift vector +#define BFV_DRAG 0x0020 ///< Show drag vector +#define BFV_TOTAL 0x0040 ///< Show total force vector +#define BFV_TORQUE 0x0080 ///< Show torque vector +/// @} + +/// \defgroup favflag Bit flags for frame axis vector render options +/// @{ +#define FAV_ENABLE 0x0001 ///< Enable frame axis vector display +#define FAV_NEGATIVE 0x0002 ///< Also show negative axes +#define FAV_VESSEL 0x0004 ///< Show vessel frame axes +#define FAV_CELBODY 0x0008 ///< Show celestial body frame axes +#define FAV_BASE 0x0010 ///< Show surface base frame axes +/// @} + /// \defgroup bltflag Bit flags for blitting operations /// @{ #define BLT_SRCCOLORKEY 0x1 ///< Use source surface colour key for transparency diff --git a/Src/Orbiter/Config.cpp b/Src/Orbiter/Config.cpp index 16124d62b..4747513e6 100644 --- a/Src/Orbiter/Config.cpp +++ b/Src/Orbiter/Config.cpp @@ -123,10 +123,10 @@ CFG_INSTRUMENTPRM CfgInstrumentPrm_default = { CFG_VISHELPPRM CfgVisHelpPrm_default = { PLN_CGRID | PLN_CONST | PLN_CNSTLABEL | PLN_CNSTLONG | PLN_CMARK, // flagPlanetarium (celestial marker flags) - BF_WEIGHT | BF_THRUST | BF_LIFT | BF_DRAG, // flagBodyforce (force display flags) + BFV_WEIGHT | BFV_THRUST | BFV_LIFT | BFV_DRAG, // flagBodyforce (force display flags) 1.0f, // scaleBodyforce (force vector scaling factor) 1.0f, // opacBodyforce (force vector opacity) - CA_VESSEL, // flagCrdAxes (axis display flags) + FAV_VESSEL, // flagCrdAxes (frame axis display flags) 1.0f, // scaleCrdAxes (axis scaling factor) 1.0f // opacCrdAxes (axis opacity) }; @@ -674,9 +674,9 @@ bool Config::Load(const char *fname) if (GetInt (ifs, "Planetarium", i)) CfgVisHelpPrm.flagPlanetarium = (DWORD)i; if (GetString (ifs, "Bodyforces", cbuf)) - sscanf (cbuf, "%u%f%f", &CfgVisHelpPrm.flagBodyforce, &CfgVisHelpPrm.scaleBodyforce, &CfgVisHelpPrm.opacBodyforce); + sscanf (cbuf, "%u%f%f", &CfgVisHelpPrm.flagBodyForce, &CfgVisHelpPrm.scaleBodyForce, &CfgVisHelpPrm.opacBodyForce); if (GetString (ifs, "CoordinateAxes", cbuf)) - sscanf (cbuf, "%u%f%f", &CfgVisHelpPrm.flagCrdAxes, &CfgVisHelpPrm.scaleCrdAxes, &CfgVisHelpPrm.opacCrdAxes); + sscanf (cbuf, "%u%f%f", &CfgVisHelpPrm.flagFrameAxes, &CfgVisHelpPrm.scaleFrameAxes, &CfgVisHelpPrm.opacFrameAxes); // debug options if (GetInt (ifs, "ShutdownMode", i) && i >= 0 && i <= 2) @@ -918,6 +918,18 @@ const void *Config::GetParam (DWORD paramtype) const return (void*)&CfgInstrumentPrm.PanelMFDHUDSize; case CFGPRM_TILEPATCHRES: return (void*)&CfgPRenderPrm.PatchRes; + case CFGPRM_FORCEVECTORFLAG: + return (void*)&CfgVisHelpPrm.flagBodyForce; + case CFGPRM_FORCEVECTORSCALE: + return (void*)&CfgVisHelpPrm.scaleBodyForce; + case CFGPRM_FORCEVECTOROPACITY: + return (void*)&CfgVisHelpPrm.opacBodyForce; + case CFGPRM_FRAMEAXISFLAG: + return (void*)&CfgVisHelpPrm.flagFrameAxes; + case CFGPRM_FRAMEAXISSCALE: + return (void*)&CfgVisHelpPrm.scaleFrameAxes; + case CFGPRM_FRAMEAXISOPACITY: + return (void*)&CfgVisHelpPrm.opacFrameAxes; default: return 0; } @@ -1073,16 +1085,16 @@ BOOL Config::Write (const char *fname) const ofs << "\n; === Visual helper parameters ===\n"; if (CfgVisHelpPrm.flagPlanetarium != CfgVisHelpPrm_default.flagPlanetarium || bEchoAll) ofs << "Planetarium = " << CfgVisHelpPrm.flagPlanetarium << '\n'; - if (CfgVisHelpPrm.flagBodyforce != CfgVisHelpPrm_default.flagBodyforce || - CfgVisHelpPrm.scaleBodyforce != CfgVisHelpPrm_default.scaleBodyforce || - CfgVisHelpPrm.opacBodyforce != CfgVisHelpPrm_default.opacBodyforce || bEchoAll) - ofs << "Bodyforces = " << CfgVisHelpPrm.flagBodyforce << ' ' << CfgVisHelpPrm.scaleBodyforce - << ' ' << CfgVisHelpPrm.opacBodyforce << '\n'; - if (CfgVisHelpPrm.flagCrdAxes != CfgVisHelpPrm_default.flagCrdAxes || - CfgVisHelpPrm.scaleCrdAxes != CfgVisHelpPrm_default.scaleCrdAxes || - CfgVisHelpPrm.opacCrdAxes != CfgVisHelpPrm_default.opacCrdAxes || bEchoAll) - ofs << "CoordinateAxes = " << CfgVisHelpPrm.flagCrdAxes << ' ' << CfgVisHelpPrm.scaleCrdAxes - << ' ' << CfgVisHelpPrm.opacCrdAxes << '\n'; + if (CfgVisHelpPrm.flagBodyForce != CfgVisHelpPrm_default.flagBodyForce || + CfgVisHelpPrm.scaleBodyForce != CfgVisHelpPrm_default.scaleBodyForce || + CfgVisHelpPrm.opacBodyForce != CfgVisHelpPrm_default.opacBodyForce || bEchoAll) + ofs << "Bodyforces = " << CfgVisHelpPrm.flagBodyForce << ' ' << CfgVisHelpPrm.scaleBodyForce + << ' ' << CfgVisHelpPrm.opacBodyForce << '\n'; + if (CfgVisHelpPrm.flagFrameAxes != CfgVisHelpPrm_default.flagFrameAxes || + CfgVisHelpPrm.scaleFrameAxes != CfgVisHelpPrm_default.scaleFrameAxes || + CfgVisHelpPrm.opacFrameAxes != CfgVisHelpPrm_default.opacFrameAxes || bEchoAll) + ofs << "CoordinateAxes = " << CfgVisHelpPrm.flagFrameAxes << ' ' << CfgVisHelpPrm.scaleFrameAxes + << ' ' << CfgVisHelpPrm.opacFrameAxes << '\n'; } if (memcmp (&CfgDebugPrm, &CfgDebugPrm_default, sizeof (CFG_DEBUGPRM)) || bEchoAll) { diff --git a/Src/Orbiter/Config.h b/Src/Orbiter/Config.h index 4dee645db..a0c0a2b41 100644 --- a/Src/Orbiter/Config.h +++ b/Src/Orbiter/Config.h @@ -18,23 +18,6 @@ #include #include "GraphicsAPI.h" -// body force modes -#define BF_ENABLE 0x0001 -#define BF_LOGSCALE 0x0002 -#define BF_WEIGHT 0x0004 -#define BF_THRUST 0x0008 -#define BF_LIFT 0x0010 -#define BF_DRAG 0x0020 -#define BF_TOTAL 0x0040 -#define BF_TORQUE 0x0080 - -// coordinate axes modes -#define CA_ENABLE 0x0001 -#define CA_NEG 0x0002 -#define CA_VESSEL 0x0004 -#define CA_CBODY 0x0008 -#define CA_BASE 0x0010 - // dynamic state propagation methods #define MAX_PROP_LEVEL 5 #define MAX_APROP_LEVEL 5 @@ -165,12 +148,12 @@ struct CFG_VISHELPPRM { // bit 5: constellation patterns bit 13: constellation boundaries // bit 6: constellation labels bit 14: celestial sphere markers // bit 7: celestial body markers - DWORD flagBodyforce; // body force vector display - float scaleBodyforce; // force vector scaling factor - float opacBodyforce; // force vector opacity factor - DWORD flagCrdAxes; // coordinate axes vector display - float scaleCrdAxes; // coordinate axes scaling factor - float opacCrdAxes; // coordinate axes opacity factor + DWORD flagBodyForce; // body force vector display + float scaleBodyForce; // force vector scaling factor + float opacBodyForce; // force vector opacity factor + DWORD flagFrameAxes; // frame axes vector display + float scaleFrameAxes; // frame axes scaling factor + float opacFrameAxes; // frame axes opacity factor }; struct CFG_DEBUGPRM { diff --git a/Src/Orbiter/DlgVishelper.cpp b/Src/Orbiter/DlgVishelper.cpp index 7eb5e2303..4f612679f 100644 --- a/Src/Orbiter/DlgVishelper.cpp +++ b/Src/Orbiter/DlgVishelper.cpp @@ -572,23 +572,23 @@ void TabForces::CreateInterface() void TabForces::UpdateControls(HWND hTab) { - DWORD vecFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagBodyforce; - bool enable = (vecFlag & BF_ENABLE); + DWORD vecFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagBodyForce; + bool enable = (vecFlag & BFV_ENABLE); SendDlgItemMessage(hTab, IDC_VH_VEC, BM_SETCHECK, enable ? BST_CHECKED : BST_UNCHECKED, 0); for (int i = IDC_VH_VEC_WEIGHT; i <= IDC_VH_VEC_OPACITY; i++) EnableWindow(GetDlgItem(hTab, i), enable ? TRUE : FALSE); - SendDlgItemMessage(hTab, IDC_VH_VEC_WEIGHT, BM_SETCHECK, vecFlag & BF_WEIGHT ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_THRUST, BM_SETCHECK, vecFlag & BF_THRUST ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_LIFT, BM_SETCHECK, vecFlag & BF_LIFT ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_DRAG, BM_SETCHECK, vecFlag & BF_DRAG ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_TOTAL, BM_SETCHECK, vecFlag & BF_TOTAL ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_TORQUE, BM_SETCHECK, vecFlag & BF_TORQUE ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_LINSCL, BM_SETCHECK, vecFlag & BF_LOGSCALE ? BST_UNCHECKED : BST_CHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_VEC_LOGSCL, BM_SETCHECK, vecFlag & BF_LOGSCALE ? BST_CHECKED : BST_UNCHECKED, 0); - - int scalePos = (int)(25.0 * (1.0 + 0.5 * log(g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleBodyforce) / log(2.0))); + SendDlgItemMessage(hTab, IDC_VH_VEC_WEIGHT, BM_SETCHECK, vecFlag & BFV_WEIGHT ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_THRUST, BM_SETCHECK, vecFlag & BFV_THRUST ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_LIFT, BM_SETCHECK, vecFlag & BFV_LIFT ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_DRAG, BM_SETCHECK, vecFlag & BFV_DRAG ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_TOTAL, BM_SETCHECK, vecFlag & BFV_TOTAL ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_TORQUE, BM_SETCHECK, vecFlag & BFV_TORQUE ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_LINSCL, BM_SETCHECK, vecFlag & BFV_LOGSCALE ? BST_UNCHECKED : BST_CHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_VEC_LOGSCL, BM_SETCHECK, vecFlag & BFV_LOGSCALE ? BST_CHECKED : BST_UNCHECKED, 0); + + int scalePos = (int)(25.0 * (1.0 + 0.5 * log(g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleBodyForce) / log(2.0))); oapiSetGaugePos(GetDlgItem(hTab, IDC_VH_VEC_SCALE), scalePos); - int opacPos = (int)(g_pOrbiter->Cfg()->CfgVisHelpPrm.opacBodyforce * 50.0); + int opacPos = (int)(g_pOrbiter->Cfg()->CfgVisHelpPrm.opacBodyForce * 50.0); oapiSetGaugePos(GetDlgItem(hTab, IDC_VH_VEC_OPACITY), opacPos); } @@ -643,18 +643,18 @@ void TabForces::OnItemClicked(HWND hTab, WORD ctrlId) bool check = (SendDlgItemMessage(hTab, ctrlId, BM_GETCHECK, 0, 0) == TRUE); DWORD flag; switch (ctrlId) { - case IDC_VH_VEC: flag = BF_ENABLE; break; - case IDC_VH_VEC_WEIGHT: flag = BF_WEIGHT; break; - case IDC_VH_VEC_THRUST: flag = BF_THRUST; break; - case IDC_VH_VEC_LIFT: flag = BF_LIFT; break; - case IDC_VH_VEC_DRAG: flag = BF_DRAG; break; - case IDC_VH_VEC_TOTAL: flag = BF_TOTAL; break; - case IDC_VH_VEC_TORQUE: flag = BF_TORQUE; break; - case IDC_VH_VEC_LINSCL: flag = BF_LOGSCALE; check = false; break; - case IDC_VH_VEC_LOGSCL: flag = BF_LOGSCALE; check = true; break; - default: flag = 0; break; + case IDC_VH_VEC: flag = BFV_ENABLE; break; + case IDC_VH_VEC_WEIGHT: flag = BFV_WEIGHT; break; + case IDC_VH_VEC_THRUST: flag = BFV_THRUST; break; + case IDC_VH_VEC_LIFT: flag = BFV_LIFT; break; + case IDC_VH_VEC_DRAG: flag = BFV_DRAG; break; + case IDC_VH_VEC_TOTAL: flag = BFV_TOTAL; break; + case IDC_VH_VEC_TORQUE: flag = BFV_TORQUE; break; + case IDC_VH_VEC_LINSCL: flag = BFV_LOGSCALE; check = false; break; + case IDC_VH_VEC_LOGSCL: flag = BFV_LOGSCALE; check = true; break; + default: flag = 0; break; } - DWORD& vecFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagBodyforce; + DWORD& vecFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagBodyForce; if (check) vecFlag |= flag; else vecFlag &= ~flag; @@ -671,7 +671,7 @@ BOOL TabForces::OnHScroll(HWND hTab, WPARAM wParam, LPARAM lParam) case SB_THUMBTRACK: case SB_LINELEFT: case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleBodyforce = (float)pow(2.0, (HIWORD(wParam) - 25) * 0.08); + g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleBodyForce = (float)pow(2.0, (HIWORD(wParam) - 25) * 0.08); return 0; } break; @@ -680,7 +680,7 @@ BOOL TabForces::OnHScroll(HWND hTab, WPARAM wParam, LPARAM lParam) case SB_THUMBTRACK: case SB_LINELEFT: case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgVisHelpPrm.opacBodyforce = (float)(HIWORD(wParam) * 0.02); + g_pOrbiter->Cfg()->CfgVisHelpPrm.opacBodyForce = (float)(HIWORD(wParam) * 0.02); return 0; } break; @@ -707,19 +707,19 @@ void TabAxes::CreateInterface() void TabAxes::UpdateControls(HWND hTab) { - DWORD crdFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagCrdAxes; - bool enable = (crdFlag & CA_ENABLE); + DWORD crdFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagFrameAxes; + bool enable = (crdFlag & FAV_ENABLE); SendDlgItemMessage(hTab, IDC_VH_CRD, BM_SETCHECK, enable ? BST_CHECKED : BST_UNCHECKED, 0); for (int i = IDC_VH_CRD_VESSEL; i <= IDC_VH_CRD_OPACITY; i++) EnableWindow(GetDlgItem(hTab, i), enable ? TRUE : FALSE); - SendDlgItemMessage(hTab, IDC_VH_CRD_VESSEL, BM_SETCHECK, crdFlag & CA_VESSEL ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_CRD_CELBODY, BM_SETCHECK, crdFlag & CA_CBODY ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_CRD_BASE, BM_SETCHECK, crdFlag & CA_BASE ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(hTab, IDC_VH_CRD_NEGATIVE, BM_SETCHECK, crdFlag & CA_NEG ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_CRD_VESSEL, BM_SETCHECK, crdFlag & FAV_VESSEL ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_CRD_CELBODY, BM_SETCHECK, crdFlag & FAV_CELBODY ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_CRD_BASE, BM_SETCHECK, crdFlag & FAV_BASE ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(hTab, IDC_VH_CRD_NEGATIVE, BM_SETCHECK, crdFlag & FAV_NEGATIVE ? BST_CHECKED : BST_UNCHECKED, 0); - int scalePos = (int)(25.0 * (1.0 + 0.5 * log(g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleCrdAxes) / log(2.0))); + int scalePos = (int)(25.0 * (1.0 + 0.5 * log(g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleFrameAxes) / log(2.0))); oapiSetGaugePos(GetDlgItem(hTab, IDC_VH_CRD_SCALE), scalePos); - int opacPos = (int)(g_pOrbiter->Cfg()->CfgVisHelpPrm.opacCrdAxes * 50.0); + int opacPos = (int)(g_pOrbiter->Cfg()->CfgVisHelpPrm.opacFrameAxes * 50.0); oapiSetGaugePos(GetDlgItem(hTab, IDC_VH_CRD_OPACITY), opacPos); } @@ -770,14 +770,14 @@ void TabAxes::OnItemClicked(HWND hTab, WORD ctrlId) bool check = (SendDlgItemMessage(hTab, ctrlId, BM_GETCHECK, 0, 0) == TRUE); DWORD flag; switch (ctrlId) { - case IDC_VH_CRD: flag = CA_ENABLE; break; - case IDC_VH_CRD_VESSEL: flag = CA_VESSEL; break; - case IDC_VH_CRD_CELBODY: flag = CA_CBODY; break; - case IDC_VH_CRD_BASE: flag = CA_BASE; break; - case IDC_VH_CRD_NEGATIVE: flag = CA_NEG; break; - default: flag = 0; break; + case IDC_VH_CRD: flag = FAV_ENABLE; break; + case IDC_VH_CRD_VESSEL: flag = FAV_VESSEL; break; + case IDC_VH_CRD_CELBODY: flag = FAV_CELBODY; break; + case IDC_VH_CRD_BASE: flag = FAV_BASE; break; + case IDC_VH_CRD_NEGATIVE: flag = FAV_NEGATIVE; break; + default: flag = 0; break; } - DWORD& crdFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagCrdAxes; + DWORD& crdFlag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagFrameAxes; if (check) crdFlag |= flag; else crdFlag &= ~flag; @@ -794,7 +794,7 @@ BOOL TabAxes::OnHScroll(HWND hTab, WPARAM wParam, LPARAM lParam) case SB_THUMBTRACK: case SB_LINELEFT: case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleCrdAxes = (float)pow(2.0, (HIWORD(wParam) - 25) * 0.08); + g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleFrameAxes = (float)pow(2.0, (HIWORD(wParam) - 25) * 0.08); return 0; } break; @@ -803,7 +803,7 @@ BOOL TabAxes::OnHScroll(HWND hTab, WPARAM wParam, LPARAM lParam) case SB_THUMBTRACK: case SB_LINELEFT: case SB_LINERIGHT: - g_pOrbiter->Cfg()->CfgVisHelpPrm.opacCrdAxes = (float)(HIWORD(wParam) * 0.02); + g_pOrbiter->Cfg()->CfgVisHelpPrm.opacFrameAxes = (float)(HIWORD(wParam) * 0.02); return 0; } break; diff --git a/Src/Orbiter/Scene.cpp b/Src/Orbiter/Scene.cpp index 2c8e92c02..6e125bb6b 100644 --- a/Src/Orbiter/Scene.cpp +++ b/Src/Orbiter/Scene.cpp @@ -557,7 +557,7 @@ void Scene::Timejump (PlanetarySystem *psys, Camera **camlist, DWORD ncam, bool static int lvlid[256]; -void Scene::Render3DLabel (const Vector &gp, char *label, double scale, DWORD colour) +void Scene::Render3DLabel (const Vector &gp, const char *label, double scale, DWORD colour) { static VERTEX_TL1TEX Vtx[4] = { {0,0,0,0,(D3DCOLOR)D3DRGBA(1,1,1,1),0.001f,0.001f}, @@ -589,7 +589,7 @@ void Scene::Render3DLabel (const Vector &gp, char *label, double scale, DWORD co w = 0; x0 = 0; v = 0; - for (char *c = label; *c; c++) { + for (const char *c = label; *c; c++) { int idx = *c - 32; sr.left = gfont_ofs[0][idx]; sr.right = sr.left + gfont_cw[0][idx]; @@ -948,13 +948,11 @@ void Scene::Render (D3DRECT* vp_rect) pstream[n]->Render (dev, ptex); if (ptex) dev->SetTexture (0, 0); - // render object vectors - should this be done without z-buffer? - bool bRenderVectors = true; - if (bRenderVectors) { - g_camera->SetFrustumLimits (1.0, 1e30); - for (i = 0; i < nobj; i++) - vobj[i]->RenderVectors (dev); - g_camera->SetFrustumLimits (npl, fpl); // reset fustrum limits + // render object vectors + if (*(DWORD*)gc->GetConfigParam(CFGPRM_FORCEVECTORFLAG) & BFV_ENABLE || *(DWORD*)gc->GetConfigParam(CFGPRM_FRAMEAXISFLAG) & FAV_ENABLE) { + g_camera->SetFrustumLimits(1.0, 1e30); + RenderVectors(); + g_camera->SetFrustumLimits(npl, fpl); // reset fustrum limits } // render focus object in cockpit view @@ -1029,3 +1027,38 @@ void Scene::RenderVesselShadows () SetDefaultMaterial(); dev->SetRenderState (D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); } + +void Scene::RenderVectors() +{ + dev->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); + dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + dev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + dev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + dev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + dev->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, TRUE); + dev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); + dev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_POINT); + dev->SetTexture(0, 0); + D3DMATERIAL7 pmtrl, mtrl = { {1,1,1,1},{1,1,1,1},{1,1,1,1},{0.2,0.2,0.2,1},40 }; + dev->GetMaterial(&pmtrl); + dev->SetMaterial(&mtrl); + + for (int i = 0; i < nobj; i++) + vobj[i]->RenderVectors(dev); + + dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + dev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + dev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + dev->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE); + dev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + dev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR); + dev->SetMaterial(&pmtrl); + + for (int i = 0; i < nobj; i++) + vobj[i]->RenderVectorLabels(dev); + + dev->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); +} \ No newline at end of file diff --git a/Src/Orbiter/Scene.h b/Src/Orbiter/Scene.h index 9690bd913..b96eb92bb 100644 --- a/Src/Orbiter/Scene.h +++ b/Src/Orbiter/Scene.h @@ -86,7 +86,7 @@ class Scene { void Render (D3DRECT* vp_rect); // Render the scene in vp using device dev - void Render3DLabel (const Vector &p, char *label, double scale = 1.0, DWORD colour = D3DRGBA(1,1,1,1)); + void Render3DLabel (const Vector &p, const char *label, double scale = 1.0, DWORD colour = D3DRGBA(1,1,1,1)); // Render text "label" at position p using current world matrix void RenderObjectMarker (oapi::Sketchpad* pSkp, const Vector &gpos, const std::string& label1, const std::string& label2 = 0, int mode = 0, int scale = 0); @@ -111,6 +111,14 @@ class Scene { double MinParticleCameraDist() const; // return the minimum distance between the camera and any particle in the scene +protected: + /** + * \brief Render vector features for each visual object if requested + * (frame axes, force vectors, etc.) + */ + void RenderVectors(); + + private: OrbiterGraphics *gc; // graphics client instance diff --git a/Src/Orbiter/VBase.cpp b/Src/Orbiter/VBase.cpp index bfe52f1ae..479eea1ae 100644 --- a/Src/Orbiter/VBase.cpp +++ b/Src/Orbiter/VBase.cpp @@ -720,25 +720,6 @@ void VBase::RenderGroundShadow (LPDIRECT3DDEVICE7 dev) } } -void VBase::SetupRenderVectorList () -{ - DWORD flag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagCrdAxes; - if ((flag & CA_ENABLE) && (flag & CA_BASE)) { - double scale = base->size * g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleCrdAxes; - double rad = base->size*0.02; - float alpha = g_pOrbiter->Cfg()->CfgVisHelpPrm.opacCrdAxes; - Vector cam (tmul (base->GRot(), g_camera->GPos()-base->GPos())); - AddVec (cam, Vector(scale,0,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PX, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,scale,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PY, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,0,scale), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PZ, D3DRGB(1,1,1)); - if (flag & CA_NEG) { - AddVec (cam, Vector(-scale,0,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NX, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,-scale,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NY, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,0,-scale), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NZ, D3DRGB(1,1,1)); - } - } -} - bool VBase::ModLighting (LPD3DLIGHT7 light) { const CelestialBody *cb = base->RefPlanet(); diff --git a/Src/Orbiter/VBase.h b/Src/Orbiter/VBase.h index 916921a69..6470175ea 100644 --- a/Src/Orbiter/VBase.h +++ b/Src/Orbiter/VBase.h @@ -31,7 +31,6 @@ class VBase: public VObject { void RenderShadows (LPDIRECT3DDEVICE7 dev); void RenderStructures (LPDIRECT3DDEVICE7 dev); void RenderGroundShadow (LPDIRECT3DDEVICE7 dev); - void SetupRenderVectorList (); const Base *GetBase() const { return base; } Vector SunDir () const { return sundir; } diff --git a/Src/Orbiter/VPlanet.cpp b/Src/Orbiter/VPlanet.cpp index fa973cb09..60dca405e 100644 --- a/Src/Orbiter/VPlanet.cpp +++ b/Src/Orbiter/VPlanet.cpp @@ -521,6 +521,20 @@ void VPlanet::RenderCloudShadows (LPDIRECT3DDEVICE7 dev) } } +void VPlanet::RenderVectors(LPDIRECT3DDEVICE7 dev) +{ + VObject::RenderVectors(dev); + RenderBaseVectors(dev); +} + +void VPlanet::RenderBaseVectors(LPDIRECT3DDEVICE7 dev) +{ + for (DWORD i = 0; i < planet->nBase(); i++) { + VBase* vbase = (VBase*)planet->GetBase(i)->GetVishandle(); + if (vbase) vbase->RenderVectors(dev); + } +} + void VPlanet::RenderBaseSurfaceTiles (LPDIRECT3DDEVICE7 dev) { for (DWORD i = 0; i < planet->nBase(); i++) { @@ -765,26 +779,6 @@ int VPlanet::ShadowPlanetOnRing (VERTEX_XYZC *&vtx, DWORD &nvtx) return nvtx; } -void VPlanet::SetupRenderVectorList () -{ - DWORD flag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagCrdAxes; - if ((flag & CA_ENABLE) && (flag & CA_CBODY)) { - double psize = planet->Size(); - double scale = g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleCrdAxes * psize*1.3; - double rad = 0.02 * psize; - float alpha = g_pOrbiter->Cfg()->CfgVisHelpPrm.opacCrdAxes; - Vector cam (tmul (planet->GRot(), g_camera->GPos()-planet->GPos())); - AddVec (cam, Vector(scale,0,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PX, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,scale,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PY, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,0,scale), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PZ, D3DRGB(1,1,1)); - if (flag & CA_NEG) { - AddVec (cam, Vector(-scale,0,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NX, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,-scale,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NY, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,0,-scale), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NZ, D3DRGB(1,1,1)); - } - } -} - bool VPlanet::ModLighting (DWORD &ambient) { // Eventually we may need to modify the direct light levels (diffuse+specular) as diff --git a/Src/Orbiter/VPlanet.h b/Src/Orbiter/VPlanet.h index 9a7a9fdaa..cddb98d57 100644 --- a/Src/Orbiter/VPlanet.h +++ b/Src/Orbiter/VPlanet.h @@ -75,6 +75,9 @@ class VPlanet: public VObject { void RenderCloudShadows (LPDIRECT3DDEVICE7 dev); // render cloud shadows on the ground + void RenderVectors(LPDIRECT3DDEVICE7 dev); + void RenderBaseVectors(LPDIRECT3DDEVICE7 dev); + void RenderBaseSurfaceTiles (LPDIRECT3DDEVICE7 dev); void RenderBaseSurfaceDecals (LPDIRECT3DDEVICE7 dev); void RenderBaseShadows (LPDIRECT3DDEVICE7 dev, float alpha); @@ -84,8 +87,6 @@ class VPlanet: public VObject { void RenderRing (LPDIRECT3DDEVICE7 dev, bool addbkg = false); // render ring system around planet - void SetupRenderVectorList (); - PatchManager *cloudmanager; HorizonManager *horizonmanager; RingManager *ringmanager; diff --git a/Src/Orbiter/Vobject.cpp b/Src/Orbiter/Vobject.cpp index 071922270..b2dca5ccc 100644 --- a/Src/Orbiter/Vobject.cpp +++ b/Src/Orbiter/Vobject.cpp @@ -17,6 +17,7 @@ #include "Log.h" #include "Astro.h" #include +#include using namespace oapi; @@ -64,12 +65,18 @@ void VObject::DestroyDeviceObjects () } } +bool veccomp(const VObject::BodyVectorRec& v1, const VObject::BodyVectorRec& v2) +{ + return v1.dist > v2.dist; // sort from furthest to nearest +} + void VObject::Update (bool moving, bool force) { if (body == g_camera->Target()) cpos.Set (-(*g_camera->GSPosPtr())); else cpos.Set (body->GPos() - g_camera->GPos()); + campos = tmul(body->GRot(), -cpos); cdist = cpos.length(); if (force) { @@ -98,6 +105,36 @@ void VObject::Update (bool moving, bool force) cpos.x,cpos.y,cpos.z,1); SetInvD3DRotation (mWorld, body->GRot()); SetD3DTranslation (mWorld, cpos); + + UpdateRenderVectors(); + std::sort(veclist.begin(), veclist.end(), veccomp); +} + +void VObject::UpdateRenderVectors() +{ + veclist.clear(); + + // render object frame axes + DWORD flag = *(DWORD*)gc->GetConfigParam(CFGPRM_FRAMEAXISFLAG); + if (flag & FAV_ENABLE) { + int tp = body->Type(); + if ((tp == OBJTP_VESSEL && flag & FAV_VESSEL) || + (tp == OBJTP_PLANET && flag & FAV_CELBODY) || + (tp == OBJTP_SURFBASE && flag & FAV_BASE)) { + + double scale = body->Size() * *(float*)gc->GetConfigParam(CFGPRM_FRAMEAXISSCALE); + double rad = body->Size() * 0.01; + float alpha = *(float*)gc->GetConfigParam(CFGPRM_FRAMEAXISOPACITY); + AddVector(Vector(scale, 0, 0), Vector(0, 0, 0), rad, std::string("+x"), Vector(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(Vector(0, scale, 0), Vector(0, 0, 0), rad, std::string("+y"), Vector(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(Vector(0, 0, scale), Vector(0, 0, 0), rad, std::string("+z"), Vector(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + if (flag & FAV_NEGATIVE) { + AddVector(Vector(-scale, 0, 0), Vector(0, 0, 0), rad, std::string("-x"), Vector(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(Vector(0, -scale, 0), Vector(0, 0, 0), rad, std::string("-y"), Vector(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + AddVector(Vector(0, 0, -scale), Vector(0, 0, 0), rad, std::string("-z"), Vector(1, 1, 1), alpha, D3DRGB(1, 1, 1)); + } + } + } } void VObject::RenderAsDisc (LPDIRECT3DDEVICE7 dev) @@ -290,97 +327,63 @@ void VObject::RenderAsSpot (LPDIRECT3DDEVICE7 dev, D3DCOLORVALUE *illumination) dev->SetRenderState (D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); } -static const int nveclist = 15; -static vecentry veclist[nveclist]; // should allow dynamic realloc -static vecentry *vecfirst = 0; -static int nvec = 0; - -void AddVec (const Vector &cam, const Vector &v, const Vector &orig, double rad, const Vector &col, float alpha, char *label, DWORD lcol, float lsize) +void VObject::AddVector (const Vector &v, const Vector &orig, double rad, const std::string& label, const Vector &col, float alpha, DWORD lcol, float lsize) { double len = v.length(); if (len < 2.0*rad) return; // too short to be rendered - if (nvec == nveclist) { - strcpy (DBG_MSG, "AddVec: Insufficient data buffer"); - return; - } - - Vector vu = v/len; - - double dist = (vu-cam).length(); - - // add entry - veclist[nvec].v = vu * len; - veclist[nvec].orig = orig; - veclist[nvec].rad = rad; - veclist[nvec].dist = dist; - veclist[nvec].col = col; - veclist[nvec].alpha = alpha; - if (label) { - strncpy (veclist[nvec].label, label, 32); - veclist[nvec].lcol = lcol; - veclist[nvec].lsize = lsize; - } else { - veclist[nvec].label[0] = '\0'; - } - - // insert into list according to tip distance of unit vector - vecentry *ve, *pve; - for (ve = vecfirst, pve = 0; ve; pve = ve, ve = ve->next) - if (ve->dist < dist) break; - - if (pve) pve->next = veclist+nvec; - else vecfirst = veclist+nvec; - veclist[nvec].next = ve; - nvec++; + Vector vu = v / len; + double dist = (vu - campos).length(); + + BodyVectorRec rec; + rec.v = v; + rec.orig = orig; + rec.rad = rad; + rec.dist = dist; + rec.col = col; + rec.alpha = alpha; + rec.label = label; + rec.lcol = lcol; + rec.lsize = lsize; + + veclist.push_back(rec); } -void VObject::SetupRenderVectorList () +void VObject::RenderVectors (LPDIRECT3DDEVICE7 dev) { + if (veclist.size()) { + float palpha = -1.0f; + Vector pcol(-1, -1, -1); + for (auto&& vec : veclist) { + if (vec.alpha != palpha || vec.col.x != pcol.x || vec.col.y != pcol.y || vec.col.z != pcol.z) { + dev->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, D3DRGBA(vec.col.x, vec.col.y, vec.col.z, vec.alpha)); + palpha = vec.alpha; pcol = vec.col; + } + DrawVector(dev, vec.v, vec.orig, vec.rad); + } + } } -void VObject::RenderVectors (LPDIRECT3DDEVICE7 dev) +void VObject::RenderVectorLabels(LPDIRECT3DDEVICE7 dev) { - nvec = 0; // reset list - vecfirst = 0; - SetupRenderVectorList (); - - if (nvec) { - float alpha, palpha = -1.0f; - dev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - dev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - dev->SetTextureStageState (0, D3DTSS_MAGFILTER, D3DTFG_POINT); - dev->SetTextureStageState (0, D3DTSS_MINFILTER, D3DTFN_POINT); - for (vecentry *ve = vecfirst; ve; ve = ve->next) { - alpha = ve->alpha; - if (alpha != palpha) - dev->SetRenderState (D3DRENDERSTATE_TEXTUREFACTOR, D3DRGBA(1,1,1,alpha)); - if (DrawVector (dev, ve->v, ve->orig, ve->rad, ve->col, alpha) && ve->label[0]) { - double scale3 = (ve->lsize >= 0 ? ve->lsize : body->Size()); - scene->Render3DLabel (mul (body->GRot(), ve->v + ve->v.unit()*(scale3*0.1)) + body->GPos(), - ve->label, scale3, ve->lcol); + if (veclist.size()) { + for (auto&& vec : veclist) { + if (vec.label.size()) { + double scale = (vec.lsize >= 0 ? vec.lsize : body->Size()); + scene->Render3DLabel (mul (body->GRot(), vec.v + vec.v.unit()*(scale*0.1)) + body->GPos(), + vec.label.c_str(), scale, vec.lcol); } } - dev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - dev->SetTextureStageState (0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); - dev->SetTextureStageState (0, D3DTSS_MINFILTER, D3DTFN_LINEAR); } } -bool VObject::DrawVector (LPDIRECT3DDEVICE7 dev, const Vector &end, const Vector &orig, double rad, const Vector &col, float opac) +bool VObject::DrawVector (LPDIRECT3DDEVICE7 dev, const Vector &end, const Vector &orig, double rad) { static const float EPS = 1e-2f; static const int nseg = 8; static const int nVtx = nseg*5; static const int nIdx0 = nseg*6 + nseg*3; static const int nIdx1 = nIdx0 + (nseg-2)*3; - static D3DMATERIAL7 pmtrl, mtrl = { - {0,0,0,1}, - {0,0,0,1}, - {0.5,0.5,0.5,1}, - {0,0,0,1}, - 10.0 - }; int i, nIdx; WORD *Idx; static D3DVERTEX *Vtx0 = 0, *Vtx = 0; @@ -426,7 +429,6 @@ bool VObject::DrawVector (LPDIRECT3DDEVICE7 dev, const Vector &end, const Vector float h = (float)end.length(); if (h < EPS) return false; float hb = max (h-4.0f*w, 0); - DWORD bZbuf; memcpy (Vtx, Vtx0, nVtx*sizeof(D3DVERTEX)); @@ -454,30 +456,14 @@ bool VObject::DrawVector (LPDIRECT3DDEVICE7 dev, const Vector &end, const Vector D3DMath_MatrixMultiply (W, mWorld, R); dev->SetTransform (D3DTRANSFORMSTATE_WORLD, &W); - Vector cp (tmul (body->GRot(), g_camera->GPos()-body->GPos())); - if (dotp (d, (end-cp).unit()) > 0) + Vector cp (tmul (body->GRot(), -cpos)); + if (dotp (d, (end - cp).unit()) > 0) Idx = Idx1, nIdx = nIdx1; else Idx = Idx0, nIdx = nIdx0; - mtrl.emissive.r = 0.5f * (mtrl.diffuse.r = (float)col.x); - mtrl.emissive.g = 0.5f * (mtrl.diffuse.g = (float)col.y); - mtrl.emissive.b = 0.5f * (mtrl.diffuse.b = (float)col.z); - if (opac < 1.0f) - mtrl.emissive.a = mtrl.diffuse.a = mtrl.ambient.a = mtrl.specular.a = opac; - dev->GetMaterial (&pmtrl); - dev->SetMaterial (&mtrl); - dev->SetTexture (0, 0); - dev->SetRenderState (D3DRENDERSTATE_SPECULARENABLE, TRUE); - dev->GetRenderState (D3DRENDERSTATE_ZENABLE, &bZbuf); - if (bZbuf) dev->SetRenderState (D3DRENDERSTATE_ZENABLE, FALSE); dev->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, Vtx, nVtx, Idx, nIdx, 0); - dev->SetMaterial (&pmtrl); - dev->SetRenderState (D3DRENDERSTATE_SPECULARENABLE, FALSE); dev->SetTransform (D3DTRANSFORMSTATE_WORLD, &mWorld); - if (bZbuf) dev->SetRenderState (D3DRENDERSTATE_ZENABLE, TRUE); - if (opac < 1.0f) - mtrl.emissive.a = mtrl.diffuse.a = mtrl.ambient.a = mtrl.specular.a = 1.0f; return true; } diff --git a/Src/Orbiter/Vobject.h b/Src/Orbiter/Vobject.h index 0b46a97d8..0e1aa18cb 100644 --- a/Src/Orbiter/Vobject.h +++ b/Src/Orbiter/Vobject.h @@ -39,6 +39,9 @@ class VObject { virtual void Update (bool moving, bool force); // Update visual to current simulation time + virtual void UpdateRenderVectors(); + // render any auxiliary vectors + virtual void Timejump (bool moving) { Update (moving, true); } // Discontinuous update @@ -54,19 +57,12 @@ class VObject { virtual void Render (LPDIRECT3DDEVICE7 dev) = 0; // Object renders itself in the 3d device - void RenderVectors (LPDIRECT3DDEVICE7 dev); - virtual void SetupRenderVectorList(); - // render any auxiliary vectors - virtual void RenderExhaust (LPDIRECT3DDEVICE7, LPDIRECTDRAWSURFACE7) {} // all classes which define VOCAPS_HASENGINES should implement this virtual void RenderBeacons (LPDIRECT3DDEVICE7) {} // allows objects to render light beacons or similar - bool DrawVector (LPDIRECT3DDEVICE7 dev, const Vector &end, const Vector &orig, double rad = 1.0, - const Vector &col = Vector(1,1,1), float opac = 1.0f); - inline double CDist () const { return cdist; } inline const Vector &CPos () const { return cpos; } inline double ScaleFactor () const { return apprad_factor; } @@ -77,6 +73,21 @@ class VObject { virtual void clbkEvent (DWORD msg, DWORD_PTR content) {} // Notification of visual event (e.g. mesh addition/deletion) + struct BodyVectorRec { + Vector v; + Vector orig; + double rad; + double dist; + Vector col; + float alpha; + std::string label; + DWORD lcol; + float lsize; + }; + + virtual void RenderVectors(LPDIRECT3DDEVICE7 dev); + virtual void RenderVectorLabels(LPDIRECT3DDEVICE7 dev); + protected: static OrbiterGraphics *gc; // inline graphics client instance @@ -94,14 +105,20 @@ class VObject { void RenderAsSpot (LPDIRECT3DDEVICE7 dev, D3DCOLORVALUE *illumination = 0); // Render distant object as circular blob with a billboard texture + void AddVector(const Vector& v, const Vector& orig, double rad, const std::string& label, const Vector& col, float alpha = 1.0f, DWORD lcol = 0, float lsize = -1.0); + + bool DrawVector(LPDIRECT3DDEVICE7 dev, const Vector& end, const Vector& orig, double rad = 1.0); + const Body *body; // reference to logical object static Scene *scene; // reference to scene D3DMATRIX mWorld; // world transform matrix MATRIX4 dmWorld; // world transformation matrix in double precision - Vector cpos; // object position relative to camera + Vector cpos; // object position relative to camera in global frame + Vector campos; // camera position in object frame double cdist; // current distance from camera double iapprad; // inverse of apparent radius + std::vector veclist; // list of body vectors to be rendered private: double apprad_factor; // auxiliary variable for apprad calculation @@ -112,20 +129,6 @@ class VObject { // ======================================================================= // nonmember definitions -struct vecentry { // structure for rendering vectors - Vector v; - Vector orig; - double rad; - double dist; - Vector col; - float alpha; - char label[32]; - DWORD lcol; - float lsize; - vecentry *next; -}; - -void AddVec (const Vector &cam, const Vector &v, const Vector &orig, double rad, const Vector &col, float alpha = 1.0, char *label = 0, DWORD lcol = 0, float lsize = -1.0); // add a vector to the render list // cam: camera position in local object frame // v: vector, rad: line radius, col: colour, alpha: opacity, label: label, lcol: label colour (0=same as vector), lsize: label size (-1=default) diff --git a/Src/Orbiter/Vvessel.cpp b/Src/Orbiter/Vvessel.cpp index 5c88328f8..9cf23ebcc 100644 --- a/Src/Orbiter/Vvessel.cpp +++ b/Src/Orbiter/Vvessel.cpp @@ -787,86 +787,61 @@ void VVessel::RenderGroundShadow (LPDIRECT3DDEVICE7 dev, const Planet *planet) } } -void VVessel::SetupRenderVectorList () +void VVessel::UpdateRenderVectors() { - Vector cam; - bool havecam = false; + VObject::UpdateRenderVectors(); - DWORD flag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagBodyforce; - if (flag & BF_ENABLE) { + DWORD flag = *(DWORD*)gc->GetConfigParam(CFGPRM_FORCEVECTORFLAG); + if (flag & BFV_ENABLE) { static double shift = 1e3, lshift = log(shift); - bool logscale = ((flag & BF_LOGSCALE) != 0); + bool logscale = ((flag & BFV_LOGSCALE) != 0); double len, scale, scale2 = vessel->size*0.02; scale = (logscale ? 1.0 : vessel->size / (vessel->Mass() * 9.81)); - double pscale = g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleBodyforce; - float alpha = g_pOrbiter->Cfg()->CfgVisHelpPrm.opacBodyforce; - char cbuf[32]; + double pscale = *(float*)gc->GetConfigParam(CFGPRM_FORCEVECTORSCALE); + float alpha = *(float*)gc->GetConfigParam(CFGPRM_FORCEVECTOROPACITY); + char cbuf[256]; Vector F; - cam.Set (tmul (vessel->GRot(), g_camera->GPos()-vessel->GPos())); - havecam = true; - - if (flag & BF_TORQUE) { - vessel->GetTorqueVector (F); - len = F.length(); - if (len) { - if (len >= 1e-2) sprintf (cbuf, "M =%sNm", FloatStr (len, 4)); - else sprintf (cbuf, "M = %0.2eNm", len); - if (logscale) len = log(len+1e-5) - log(1e-5); else len *= scale; - AddVec (cam, F.unit()*(len*pscale), Vector(0,0,0), scale2*0.5, Vector(1,0,1), alpha, cbuf, D3DRGB (1,0,1), (float)(0.5*vessel->size)); - } - } - if (flag & BF_WEIGHT) { - vessel->GetWeightVector (F); + + if ((flag & BFV_WEIGHT) && vessel->GetWeightVector (F)) { sprintf (cbuf, "G =%sN", FloatStr (len = F.length(), 4)); if (logscale) len = log(len+shift) - lshift; else len *= scale; - AddVec (cam, F.unit()*(len*pscale), Vector(0,0,0), scale2, Vector (1,1,0), alpha, cbuf, D3DRGB (1,1,0)); + AddVector (F.unit()*(len*pscale), Vector(0,0,0), scale2, std::string(cbuf), Vector (1,1,0), alpha, D3DRGB (1,1,0)); } - if ((flag & BF_THRUST) && vessel->GetThrustVector (F)) { + if ((flag & BFV_THRUST) && vessel->GetThrustVector (F)) { sprintf (cbuf, "T =%sN", FloatStr (len = F.length(), 4)); if (logscale) len = log(len+shift) - lshift; else len *= scale; - AddVec (cam, F.unit()*(len*pscale), Vector(0,0,0), scale2, Vector (0,0,1), alpha, cbuf, D3DRGB (0.5,0.5,1)); + AddVector (F.unit()*(len*pscale), Vector(0,0,0), scale2, std::string(cbuf), Vector (0,0,1), alpha, D3DRGB (0.5,0.5,1)); } - if ((flag & BF_LIFT) && vessel->GetLiftVector (F)) { - sprintf (cbuf, "L =%sN", FloatStr (len = vessel->Lift, 4)); - double alen = fabs(len); - if (logscale) alen = log(alen+shift) - lshift; else alen *= scale; - AddVec (cam, F.unit()*(alen*pscale), Vector(0,0,0), scale2, Vector (0,1,0), alpha, cbuf, D3DRGB (0.5,1,0.5)); + if ((flag & BFV_LIFT) && vessel->GetLiftVector (F)) { + sprintf (cbuf, "L =%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,1,0), alpha, D3DRGB (0.5,1,0.5)); } - if ((flag & BF_DRAG) && vessel->GetDragVector (F)) { + if ((flag & BFV_DRAG) && vessel->GetDragVector (F)) { sprintf (cbuf, "D =%sN", FloatStr (len = vessel->Drag, 4)); if (logscale) len = log(len+shift) - lshift; else len *= scale; - AddVec (cam, F.unit()*(len*pscale), Vector(0,0,0), scale2, Vector (1,0,0), alpha, cbuf, D3DRGB (1,0.5,0.5)); + AddVector (F.unit()*(len*pscale), Vector(0,0,0), scale2, std::string(cbuf), Vector (1,0,0), alpha, D3DRGB (1,0.5,0.5)); } - if (flag & BF_TOTAL) { - vessel->GetForceVector (F); + if ((flag & BFV_TOTAL) && vessel->GetForceVector (F)) { sprintf (cbuf, "F =%sN", FloatStr (len = F.length(), 4)); if (logscale) len = log(len+shift) - lshift; else len *= scale; - AddVec (cam, F.unit()*(len*pscale), Vector(0,0,0), scale2, Vector (1,1,1), alpha, cbuf, D3DRGB (1,1,1)); + AddVector (F.unit()*(len*pscale), Vector(0,0,0), scale2, std::string(cbuf), Vector (1,1,1), alpha, D3DRGB (1,1,1)); } if (1) { for (int i = 0; i < vessel->nforcevec; i++) { F = vessel->forcevec[i]; sprintf (cbuf, "F =%sN", FloatStr (len = F.length(), 4)); len *= 1e-2; - //if (logscale) len = log(len+shift) - lshift; else len *= scale; - AddVec (cam, F.unit()*(len*pscale), vessel->forcepos[i], scale2, Vector (0,1,1), alpha, cbuf, D3DRGB (1,1,1)); + if (logscale) len = log(len+shift) - lshift; else len *= scale; + AddVector (F.unit()*(len*pscale), vessel->forcepos[i], scale2, std::string(cbuf), Vector (0,1,1), alpha, D3DRGB (1,1,1)); } } - } - flag = g_pOrbiter->Cfg()->CfgVisHelpPrm.flagCrdAxes; - if ((flag & CA_ENABLE) && (flag & CA_VESSEL)) { - double scale = vessel->size * g_pOrbiter->Cfg()->CfgVisHelpPrm.scaleCrdAxes; - double rad = vessel->size*0.02; - float alpha = g_pOrbiter->Cfg()->CfgVisHelpPrm.opacCrdAxes; - if (!havecam) - cam.Set (tmul (vessel->GRot(), g_camera->GPos()-vessel->GPos())); - AddVec (cam, Vector(scale,0,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PX, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,scale,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PY, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,0,scale), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_PZ, D3DRGB(1,1,1)); - if (flag & CA_NEG) { - AddVec (cam, Vector(-scale,0,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NX, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,-scale,0), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NY, D3DRGB(1,1,1)); - AddVec (cam, Vector(0,0,-scale), Vector(0,0,0), rad, Vector(0.5,0.5,0.5), alpha, LABEL_NZ, D3DRGB(1,1,1)); + if ((flag & BFV_TORQUE) && vessel->GetTorqueVector(F)) { + if (len = F.length()) { + sprintf(cbuf, "M =%sNm", FloatStr(len, 4)); + if (logscale) len = log(len + 1e-5) - log(1e-5); else len *= scale * 1e5; + AddVector(F.unit() * (len * pscale), Vector(0, 0, 0), scale2 * 0.5, std::string(cbuf), Vector(1, 0, 1), alpha, D3DRGB(1, 0, 1), (float)(0.5 * vessel->size)); + } } } } diff --git a/Src/Orbiter/Vvessel.h b/Src/Orbiter/Vvessel.h index b4c71dd84..a9db6d783 100644 --- a/Src/Orbiter/Vvessel.h +++ b/Src/Orbiter/Vvessel.h @@ -40,6 +40,7 @@ class VVessel: public VObject { inline bool ExtRenderPass () const { return bExtRenderPass; } void CheckResolution (double iar); void Update (bool moving, bool force); + void UpdateRenderVectors(); void Timejump (bool moving); void Render (LPDIRECT3DDEVICE7 dev); void Render (LPDIRECT3DDEVICE7 dev, bool internalpass); @@ -47,7 +48,6 @@ class VVessel: public VObject { void RenderExhaust (LPDIRECT3DDEVICE7 dev, LPDIRECTDRAWSURFACE7 defaulttex); void RenderGroundShadow (LPDIRECT3DDEVICE7 dev, const Planet *planet); void RenderAttachmentMarkers (LPDIRECT3DDEVICE7 dev, bool pa); - void SetupRenderVectorList (); bool MeshgroupTransform (const MESHGROUP_TRANSFORM &mt) const; bool MeshgroupTransform (const MESHGROUP_TRANSFORM &mt, Mesh *mesh, UINT grp) const; bool MeshTransform (const MESHGROUP_TRANSFORM &mt, Mesh *mesh) const;