Skip to content

Commit

Permalink
Projection: plate carree (#2856)
Browse files Browse the repository at this point in the history
* Cleanup
- implementation of 3 methods in base class
- Removed corresponding overrides in several derived classes
- Follow Qt's recommendation to code style (Q_DECL_OVERRIDE -> override)

* Added new projection: ProjectionCylinderFill (derived from ProjectionCylinder)
- Called Equirectangular to the users, a projection with automated windows stretching
- Inhibit zooming and panning for the new projection.
  • Loading branch information
gzotti authored Dec 10, 2022
1 parent 982571c commit fd8cf36
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 248 deletions.
28 changes: 28 additions & 0 deletions src/core/StelCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ StelProjectorP StelCore::getProjection(StelProjector::ModelViewTranformP modelVi
case ProjectionCylinder:
prj = StelProjectorP(new StelProjectorCylinder(modelViewTransform));
break;
case ProjectionCylinderFill:
prj = StelProjectorP(new StelProjectorCylinderFill(modelViewTransform));
break;
case ProjectionMercator:
prj = StelProjectorP(new StelProjectorMercator(modelViewTransform));
break;
Expand Down Expand Up @@ -479,6 +482,12 @@ void StelCore::windowHasBeenResized(qreal x, qreal y, qreal width, qreal height)
currentProjectorParams.viewportXywh.set(qRound(x), qRound(y), qRound(width), qRound(height));
currentProjectorParams.viewportCenter.set(x+(0.5+currentProjectorParams.viewportCenterOffset.v[0])*width, y+(0.5+currentProjectorParams.viewportCenterOffset.v[1])*height);
currentProjectorParams.viewportFovDiameter = qMin(width,height);

if (currentProjectionType==ProjectionType::ProjectionCylinderFill)
{
currentProjectorParams.widthStretch=0.5*width/height;
currentProjectorParams.viewportFovDiameter = height;
}
}

/*************************************************************************
Expand Down Expand Up @@ -544,8 +553,27 @@ void StelCore::setCurrentProjectionType(ProjectionType type)
{
if(type!=currentProjectionType)
{
QSettings* conf = StelApp::getInstance().getSettings();

currentProjectionType=type;
updateMaximumFov();
if (currentProjectionType==ProjectionType::ProjectionCylinderFill)
{
// Save whatever stretch is present into config.ini. This value is saved just temporarily until switching back to another projection and will not be loaded on startup.
// (To configure a stretch at startup, use startup.ssc script.)
conf->setValue("projection/width_stretch", currentProjectorParams.widthStretch);
currentProjectorParams.fov=180.f;
currentProjectorParams.widthStretch=0.5*currentProjectorParams.viewportXywh[2]/currentProjectorParams.viewportXywh[3];
currentProjectorParams.viewportFovDiameter = currentProjectorParams.viewportXywh[3];
Q_ASSERT(movementMgr);
movementMgr->setViewportVerticalOffsetTarget(0.);
movementMgr->zoomTo(180., 0.5);
}
else
{
// reset to what is stored in config.ini
currentProjectorParams.widthStretch=conf->value("projection/width_stretch", 1.0).toDouble();
}

emit currentProjectionTypeChanged(type);
emit currentProjectionTypeKeyChanged(getCurrentProjectionTypeKey());
Expand Down
1 change: 1 addition & 0 deletions src/core/StelCore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class StelCore : public QObject
ProjectionMercator, //!< Mercator projection
ProjectionMiller, //!< Miller cylindrical projection
ProjectionCylinder, //!< Cylinder projection
ProjectionCylinderFill //!< Cylinder projection, no zoom or movement allowed
};
Q_ENUM(ProjectionType)

Expand Down
18 changes: 18 additions & 0 deletions src/core/StelMovementMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,24 @@ void StelMovementMgr::setViewDirectionJ2000(const Vec3d& v)

void StelMovementMgr::panView(const double deltaAz, const double deltaAlt)
{
if (core->getCurrentProjectionType()==StelCore::ProjectionCylinderFill) // Inhibit any motion in this projection!
{
Vec3d tmp;
switch (mountMode){
case MountEquinoxEquatorial:
StelUtils::spheToRect(M_PI, 0., tmp);
break;
default:
StelUtils::spheToRect(0., 0., tmp);
break;
}

setViewDirectionJ2000(mountFrameToJ2000(tmp));
setViewUpVector(Vec3d(0., 0., 1.));

return;
}

// DONE 2016-12 FIX UP VECTOR PROBLEM
// The function is called in update loops, so make a quick check for exit.
if ((deltaAz==0.) && (deltaAlt==0.))
Expand Down
12 changes: 8 additions & 4 deletions src/core/StelMovementMgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "StelModule.hpp"
#include "StelObjectType.hpp"
#include "VecMath.hpp"
#include "StelCore.hpp"
#include <QTimeLine>
#include <QTimer>
#include <QCursor>
Expand Down Expand Up @@ -479,9 +480,15 @@ private slots:
double maxFov; // Maximum FOV in degrees. Depends on projection.
double userMaxFov; // Custom setting. Can be useful in a planetarium context.
double deltaFov; // requested change of FOV (degrees) used during zooming.
StelCore* core; // The core on which the movement are applied
QSettings* conf;
class StelObjectMgr* objectMgr;
void setFov(double f)
{
currentFov=qBound(minFov, f, maxFov);
if (core->getCurrentProjectionType()==StelCore::ProjectionCylinderFill)
currentFov=180.0;
else
currentFov=qBound(minFov, f, maxFov);
}
// immediately add deltaFov argument to FOV - does not change private var.
void changeFov(double deltaFov);
Expand All @@ -494,9 +501,6 @@ private slots:
//! Make the first screen position correspond to the second (useful for mouse dragging and also time dragging.)
void dragView(int x1, int y1, int x2, int y2);

StelCore* core; // The core on which the movement are applied
QSettings* conf;
class StelObjectMgr* objectMgr;
bool flagLockEquPos; // Define if the equatorial position is locked
bool flagTracking; // Define if the selected object is followed
bool flagInhibitAllAutomoves; // Required for special installations: If true, there is no automatic centering etc.
Expand Down
2 changes: 1 addition & 1 deletion src/core/StelProjector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ void StelProjector::init(const StelProjectorParams& params)
flipHorz = params.flipHorz ? -1.f : 1.f;
flipVert = params.flipVert ? -1.f : 1.f;
viewportFovDiameter = params.viewportFovDiameter * devicePixelsPerPixel;
pixelPerRad = 0.5f * static_cast<float>(viewportFovDiameter) / fovToViewScalingFactor(params.fov*(static_cast<float>(M_PI)/360.f));
pixelPerRad = 0.5f * static_cast<float>(viewportFovDiameter) / fovToViewScalingFactor(params.fov*(static_cast<float>(M_PI/360.)));
widthStretch = params.widthStretch;
computeBoundingCap();
}
Expand Down
42 changes: 21 additions & 21 deletions src/core/StelProjector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,18 @@ class StelProjector
class Mat4dTransform: public ModelViewTranform
{
public:
Mat4dTransform(const Mat4d& altAzToWorld, const Mat4d& vertexToAltAzPos);
void forward(Vec3d& v) const Q_DECL_OVERRIDE;
void backward(Vec3d& v) const Q_DECL_OVERRIDE;
void forward(Vec3f& v) const Q_DECL_OVERRIDE;
void backward(Vec3f& v) const Q_DECL_OVERRIDE;
void combine(const Mat4d& m) Q_DECL_OVERRIDE;
Mat4d getApproximateLinearTransfo() const Q_DECL_OVERRIDE;
ModelViewTranformP clone() const Q_DECL_OVERRIDE;
QByteArray getForwardTransformShader() const Q_DECL_OVERRIDE;
void setForwardTransformUniforms(QOpenGLShaderProgram& program) const Q_DECL_OVERRIDE;
QByteArray getBackwardTransformShader() const Q_DECL_OVERRIDE;
void setBackwardTransformUniforms(QOpenGLShaderProgram& program) const Q_DECL_OVERRIDE;
Mat4dTransform(const Mat4d& altAzToWorld, const Mat4d& vertexToAltAzPos);
void forward(Vec3d& v) const override;
void backward(Vec3d& v) const override;
void forward(Vec3f& v) const override;
void backward(Vec3f& v) const override;
void combine(const Mat4d& m) override;
Mat4d getApproximateLinearTransfo() const override;
ModelViewTranformP clone() const override;
QByteArray getForwardTransformShader() const override;
void setForwardTransformUniforms(QOpenGLShaderProgram& program) const override;
QByteArray getBackwardTransformShader() const override;
void setBackwardTransformUniforms(QOpenGLShaderProgram& program) const override;

private:
Mat4dTransform(const Mat4dTransform& src) = default;
Expand Down Expand Up @@ -126,7 +126,7 @@ class StelProjector
, devicePixelsPerPixel(1)
, widthStretch(1) {}

Vector4<int> viewportXywh; //! posX, posY, width, height
Vec4i viewportXywh; //! posX, posY, width, height
float fov; //! FOV in degrees
bool gravityLabels; //! the flag to use gravity labels or not
float defaultAngleForGravityText;//! a rotation angle to apply to gravity text (only if gravityLabels is set to false)
Expand All @@ -145,7 +145,7 @@ class StelProjector
virtual ~StelProjector() {}

///////////////////////////////////////////////////////////////////////////
// Methods which must be reimplemented by all instance of StelProjector
// Methods which must be reimplemented by all subclasses of StelProjector
//! Get a human-readable name for this projection type
virtual QString getNameI18() const = 0;
//! Get a human-readable short description for this projection type
Expand All @@ -164,7 +164,7 @@ class StelProjector
//! Apply the transformation in the backward projection in place.
virtual bool backward(Vec3d& v) const = 0;
//! Return the small zoom increment to use at the given FOV for nice movements
virtual float deltaZoom(float fov) const = 0;
virtual float deltaZoom(float fov) const {return fov;}
//! Returns GLSL code that can be used in a shader to implement forward transformation
virtual QByteArray getForwardTransformShader() const = 0;
//! Sets the necessary uniforms so that the shader returned by getForwardTransformShader can work
Expand All @@ -181,9 +181,9 @@ class StelProjector
bool intersectViewportDiscontinuity(const SphericalCap& cap) const;

//! Convert a Field Of View radius value in radians in ViewScalingFactor (used internally)
virtual float fovToViewScalingFactor(float fov) const = 0;
virtual float fovToViewScalingFactor(float fov) const {return fov;}
//! Convert a ViewScalingFactor value (used internally) in Field Of View radius in radians
virtual float viewScalingFactorToFov(float vsf) const = 0;
virtual float viewScalingFactorToFov(float vsf) const { return vsf;}

//! Get the current state of the flag which decides whether to
//! arrage labels so that they are aligned with the bottom of a 2d
Expand Down Expand Up @@ -347,19 +347,19 @@ class StelProjector
widthStretch(1.0) {}

//! Return whether the projection presents discontinuities. Used for optimization.
virtual bool hasDiscontinuity() const =0;
virtual bool hasDiscontinuity() const {return false;}
//! Determine whether a great circle connection p1 and p2 intersects with a projection discontinuity.
//! For many projections without discontinuity, this should return always false, but for other like
//! cylindrical projection it will return true if the line cuts the wrap-around line (i.e. at lon=180 if the observer look at lon=0).
virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const = 0;
virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const {return false;}

//! Determine whether a cap intersects with a projection discontinuity.
virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const = 0;
virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const {return false;}

//! Initialize the bounding cap.
virtual void computeBoundingCap();

ModelViewTranformP modelViewTransform; // Operator to apply (if not Q_NULLPTR) before the modelview projection step
ModelViewTranformP modelViewTransform; // Operator to apply (if not nullptr) before the modelview projection step

float flipHorz,flipVert; // Whether to flip in horizontal or vertical directions. Values only -1 (flip) or +1 (no flip).
float pixelPerRad; // pixel per rad at the center of the viewport disk
Expand Down
Loading

0 comments on commit fd8cf36

Please sign in to comment.