00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _STELPROJECTOR_HPP_
00021 #define _STELPROJECTOR_HPP_
00022
00023 #include "StelProjectorType.hpp"
00024 #include "VecMath.hpp"
00025 #include "StelSphereGeometry.hpp"
00026
00034 class StelProjector
00035 {
00036 public:
00037 friend class StelPainter;
00038 friend class StelCore;
00039
00042 enum StelProjectorMaskType
00043 {
00044 MaskNone,
00045 MaskDisk
00046 };
00047
00050 struct StelProjectorParams
00051 {
00052 StelProjectorParams() : viewportXywh(0, 0, 256, 256), fov(60.f), gravityLabels(false), defautAngleForGravityText(0.f), maskType(MaskNone), viewportCenter(128.f, 128.f), flipHorz(false), flipVert(false) {;}
00053 Vector4<int> viewportXywh;
00054 float fov;
00055 bool gravityLabels;
00056 float defautAngleForGravityText;
00057 StelProjectorMaskType maskType;
00058 float zNear, zFar;
00059 Vec2f viewportCenter;
00060 float viewportFovDiameter;
00061 bool flipHorz, flipVert;
00062 };
00063
00065 virtual ~StelProjector() {;}
00066
00068
00070 virtual QString getNameI18() const = 0;
00072 virtual QString getDescriptionI18() const {return "No description";}
00074 QString getHtmlSummary() const;
00076 virtual float getMaxFov() const = 0;
00083 virtual bool forward(Vec3f& v) const = 0;
00085 virtual bool backward(Vec3d& v) const = 0;
00087 virtual float deltaZoom(float fov) const = 0;
00088
00092 bool intersectViewportDiscontinuity(const Vec3d& p1, const Vec3d& p2) const
00093 {
00094 return hasDiscontinuity() && intersectViewportDiscontinuityInternal(modelViewMatrix*p1, modelViewMatrix*p2);
00095 }
00096
00097 bool intersectViewportDiscontinuity(const SphericalCap& cap) const
00098 {
00099 return hasDiscontinuity() && intersectViewportDiscontinuityInternal(modelViewMatrix*cap.n, cap.d);
00100 }
00101
00103 virtual float fovToViewScalingFactor(float fov) const = 0;
00105 virtual float viewScalingFactorToFov(float vsf) const = 0;
00106
00110 bool getFlagGravityLabels() const { return gravityLabels; }
00111
00113 const Vec4i& getViewport() const {return viewportXywh;}
00114
00116 Vec2f getViewportCenter() const
00117 {
00118 return Vec2f(viewportCenter[0]-viewportXywh[0],viewportCenter[1]-viewportXywh[1]);
00119 }
00120
00122 int getViewportPosX() const {return viewportXywh[0];}
00124 int getViewportPosY() const {return viewportXywh[1];}
00126 int getViewportWidth() const {return viewportXywh[2];}
00128 int getViewportHeight() const {return viewportXywh[3];}
00129
00135 SphericalRegionP getViewportConvexPolygon(float marginX=0., float marginY=0.) const;
00136
00138 const SphericalCap& getBoundingCap() const {return boundingCap;}
00139
00141 float getPixelPerRadAtCenter() const {return pixelPerRad;}
00142
00144 float getFov() const {return 360.f/M_PI*viewScalingFactorToFov(0.5f*viewportFovDiameter/pixelPerRad);}
00145
00147 bool needGlFrontFaceCW() const {return (flipHorz*flipVert < 0.f);}
00148
00150
00153 bool checkInViewport(const Vec3d& pos) const
00154 {
00155 return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
00156 pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(viewportXywh[0] + viewportXywh[2]));
00157 }
00158
00161 bool checkInViewport(const Vec3f& pos) const
00162 {
00163 return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
00164 pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(viewportXywh[0] + viewportXywh[2]));
00165 }
00166
00169 Vec3d viewPortIntersect(const Vec3d& p1, const Vec3d& p2) const
00170 {
00171 Vec3d v1=p1;
00172 Vec3d v2=p2;
00173 Vec3d v;
00174 for (int i=0;i<8;++i)
00175 {
00176 v=(v1+v2)*0.5;
00177 if (!checkInViewport(v))
00178 v2=v;
00179 else
00180 v1=v;
00181 }
00182 return v;
00183 }
00184
00189 inline bool project(const Vec3d& v, Vec3d& win) const
00190 {
00191 win = v;
00192 return projectInPlace(win);
00193 }
00194
00199 inline bool project(const Vec3f& v, Vec3f& win) const
00200 {
00201 win = v;
00202 return projectInPlace(win);
00203 }
00204
00205 virtual void project(int n, const Vec3d* in, Vec3f* out)
00206 {
00207 Vec3d v;
00208 for (int i = 0; i < n; ++i, ++out)
00209 {
00210 v = in[i];
00211 v.transfo4d(modelViewMatrix);
00212 out->set(v[0], v[1], v[2]);
00213 forward(*out);
00214 out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00215 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00216 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00217 }
00218 }
00219
00220 virtual void project(int n, const Vec3f* in, Vec3f* out)
00221 {
00222 for (int i = 0; i < n; ++i, ++out)
00223 {
00224 *out=in[i];
00225 out->transfo4d(modelViewMatrixf);
00226 forward(*out);
00227 out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00228 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00229 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00230 }
00231 }
00232
00236 inline bool projectInPlace(Vec3d& vd) const
00237 {
00238 vd.transfo4d(modelViewMatrix);
00239 Vec3f v(vd[0], vd[1], vd[2]);
00240 const bool rval = forward(v);
00241
00242
00243
00244
00245 vd[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
00246 vd[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
00247 vd[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
00248 return rval;
00249 }
00250
00254 inline bool projectInPlace(Vec3f& v) const
00255 {
00256 v.transfo4d(modelViewMatrixf);
00257 const bool rval = forward(v);
00258
00259
00260
00261
00262 v[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
00263 v[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
00264 v[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
00265 return rval;
00266 }
00267
00272 bool projectCheck(const Vec3d& v, Vec3d& win) const {return (project(v, win) && checkInViewport(win));}
00273
00278 bool projectCheck(const Vec3f& v, Vec3f& win) const {return (project(v, win) && checkInViewport(win));}
00279
00284 bool unProject(const Vec3d& win, Vec3d& v) const {return unProject(win[0], win[1], v);}
00285 bool unProject(double x, double y, Vec3d& v) const;
00286
00293 bool projectLineCheck(const Vec3d& v1, Vec3d& win1, const Vec3d& v2, Vec3d& win2) const
00294 {return project(v1, win1) && project(v2, win2) && (checkInViewport(win1) || checkInViewport(win2));}
00295
00297 const Mat4d& getModelViewMatrix() const {return modelViewMatrix;}
00298
00300 Mat4f getProjectionMatrix() const {return Mat4f(2.f/viewportXywh[2], 0, 0, 0, 0, 2.f/viewportXywh[3], 0, 0, 0, 0, -1., 0., -(2.f*viewportXywh[0] + viewportXywh[2])/viewportXywh[2], -(2.f*viewportXywh[1] + viewportXywh[3])/viewportXywh[3], 0, 1);}
00301
00304 static const QString maskTypeToString(StelProjectorMaskType type);
00306 static StelProjectorMaskType stringToMaskType(const QString &s);
00307
00309 StelProjectorMaskType getMaskType(void) const {return maskType;}
00310
00311 protected:
00313 StelProjector(const Mat4d& modelViewMat) : modelViewMatrix(modelViewMat),
00314 modelViewMatrixf(modelViewMat[0], modelViewMat[1], modelViewMat[2], modelViewMat[3],
00315 modelViewMat[4], modelViewMat[5], modelViewMat[6], modelViewMat[7],
00316 modelViewMat[8], modelViewMat[9], modelViewMat[10], modelViewMat[11],
00317 modelViewMat[12], modelViewMat[13], modelViewMat[14], modelViewMat[15]) {;}
00319 virtual bool hasDiscontinuity() const =0;
00323 virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const = 0;
00324
00326 virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const = 0;
00327
00329 virtual void computeBoundingCap();
00330
00331 Mat4d modelViewMatrix;
00332 Mat4f modelViewMatrixf;
00333 float flipHorz,flipVert;
00334 float pixelPerRad;
00335 StelProjectorMaskType maskType;
00336 float zNear, oneOverZNearMinusZFar;
00337 Vec4i viewportXywh;
00338 Vec2f viewportCenter;
00339 float viewportFovDiameter;
00340 bool gravityLabels;
00341 float defautAngleForGravityText;
00342 SphericalCap boundingCap;
00343
00344 private:
00346 void init(const StelProjectorParams& param);
00347 };
00348
00349 #endif // _STELPROJECTOR_HPP_