Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/schnepe2/orbiter into main
Browse files Browse the repository at this point in the history
  • Loading branch information
schnepe2 committed Nov 2, 2022
2 parents 7c7ca27 + 11b70b4 commit 5424cae
Show file tree
Hide file tree
Showing 28 changed files with 701 additions and 788 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -88,7 +88,7 @@ jobs:

- name: Upload Build Artifact
if: ${{ github.ref == 'refs/heads/main' }}
uses: actions/upload-artifact@v3.1.0
uses: actions/upload-artifact@v3.1.1
with:
name: Orbiter-${{ matrix.architecture }}
# A file, directory or wildcard pattern that describes what to upload
Expand Down
43 changes: 43 additions & 0 deletions OVP/D3D7Client/Scene.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions OVP/D3D7Client/Scene.h
Expand Up @@ -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:
Expand Down
177 changes: 175 additions & 2 deletions OVP/D3D7Client/VObject.cpp
Expand Up @@ -30,6 +30,7 @@
#include "Camera.h"
#include "Texture.h"
#include "D3D7Util.h"
#include <algorithm>

using namespace oapi;

Expand Down Expand Up @@ -87,15 +88,20 @@ 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;

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
Expand All @@ -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};
Expand Down Expand Up @@ -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;
}
35 changes: 34 additions & 1 deletion OVP/D3D7Client/VObject.h
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand All @@ -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<BodyVectorRec> veclist; ///< list of body vectors to be rendered
};

#endif // !__VOBJECT_H

0 comments on commit 5424cae

Please sign in to comment.