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), maskType(MaskNone), viewportCenter(128.f, 128.f), flipHorz(false), flipVert(false) {;}
00053 Vector4<int> viewportXywh;
00054 float fov;
00055 bool gravityLabels;
00056 StelProjectorMaskType maskType;
00057 float zNear, zFar;
00058 Vec2f viewportCenter;
00059 float viewportFovDiameter;
00060 bool flipHorz, flipVert;
00061 };
00062
00064 virtual ~StelProjector() {;}
00065
00067
00069 virtual QString getNameI18() const = 0;
00071 virtual QString getDescriptionI18() const {return "No description";}
00073 QString getHtmlSummary() const;
00075 virtual float getMaxFov() const = 0;
00082 virtual bool forward(Vec3f& v) const = 0;
00084 virtual bool backward(Vec3d& v) const = 0;
00086 virtual float deltaZoom(float fov) const = 0;
00087
00091 bool intersectViewportDiscontinuity(const Vec3d& p1, const Vec3d& p2) const
00092 {
00093 return hasDiscontinuity() && intersectViewportDiscontinuityInternal(modelViewMatrix*p1, modelViewMatrix*p2);
00094 }
00095
00096 bool intersectViewportDiscontinuity(const SphericalCap& cap) const
00097 {
00098 return hasDiscontinuity() && intersectViewportDiscontinuityInternal(modelViewMatrix*cap.n, cap.d);
00099 }
00100
00102 virtual float fovToViewScalingFactor(float fov) const = 0;
00104 virtual float viewScalingFactorToFov(float vsf) const = 0;
00105
00109 bool getFlagGravityLabels() const { return gravityLabels; }
00110
00112 const Vec4i& getViewport() const {return viewportXywh;}
00113
00115 Vec2f getViewportCenter() const
00116 {
00117 return Vec2f(viewportCenter[0]-viewportXywh[0],viewportCenter[1]-viewportXywh[1]);
00118 }
00119
00121 int getViewportPosX() const {return viewportXywh[0];}
00123 int getViewportPosY() const {return viewportXywh[1];}
00125 int getViewportWidth() const {return viewportXywh[2];}
00127 int getViewportHeight() const {return viewportXywh[3];}
00128
00134 SphericalRegionP getViewportConvexPolygon(float marginX=0., float marginY=0.) const;
00135
00137 const SphericalCap& getBoundingCap() const {return boundingCap;}
00138
00140 float getPixelPerRadAtCenter() const {return pixelPerRad;}
00141
00143 float getFov() const {return 360.f/M_PI*viewScalingFactorToFov(0.5f*viewportFovDiameter/pixelPerRad);}
00144
00146 bool needGlFrontFaceCW() const {return (flipHorz*flipVert < 0.f);}
00147
00149
00152 bool checkInViewport(const Vec3d& pos) const
00153 {
00154 return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
00155 pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(viewportXywh[0] + viewportXywh[2]));
00156 }
00157
00160 bool checkInViewport(const Vec3f& pos) const
00161 {
00162 return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
00163 pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(viewportXywh[0] + viewportXywh[2]));
00164 }
00165
00168 Vec3d viewPortIntersect(const Vec3d& p1, const Vec3d& p2) const
00169 {
00170 Vec3d v1=p1;
00171 Vec3d v2=p2;
00172 Vec3d v;
00173 for (int i=0;i<8;++i)
00174 {
00175 v=(v1+v2)*0.5;
00176 if (!checkInViewport(v))
00177 v2=v;
00178 else
00179 v1=v;
00180 }
00181 return v;
00182 }
00183
00188 inline bool project(const Vec3d& v, Vec3d& win) const
00189 {
00190 win = v;
00191 return projectInPlace(win);
00192 }
00193
00198 inline bool project(const Vec3f& v, Vec3f& win) const
00199 {
00200 win = v;
00201 return projectInPlace(win);
00202 }
00203
00204 virtual void project(int n, const Vec3d* in, Vec3f* out)
00205 {
00206 Vec3d v;
00207 for (int i = 0; i < n; ++i, ++out)
00208 {
00209 v = in[i];
00210 v.transfo4d(modelViewMatrix);
00211 out->set(v[0], v[1], v[2]);
00212 forward(*out);
00213 out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00214 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00215 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00216 }
00217 }
00218
00219 virtual void project(int n, const Vec3f* in, Vec3f* out)
00220 {
00221 for (int i = 0; i < n; ++i, ++out)
00222 {
00223 *out=in[i];
00224 out->transfo4d(modelViewMatrixf);
00225 forward(*out);
00226 out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00227 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00228 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00229 }
00230 }
00231
00235 inline bool projectInPlace(Vec3d& vd) const
00236 {
00237 vd.transfo4d(modelViewMatrix);
00238 Vec3f v(vd[0], vd[1], vd[2]);
00239 const bool rval = forward(v);
00240
00241
00242
00243
00244 vd[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
00245 vd[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
00246 vd[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
00247 return rval;
00248 }
00249
00253 inline bool projectInPlace(Vec3f& v) const
00254 {
00255 v.transfo4d(modelViewMatrixf);
00256 const bool rval = forward(v);
00257
00258
00259
00260
00261 v[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
00262 v[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
00263 v[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
00264 return rval;
00265 }
00266
00271 bool projectCheck(const Vec3d& v, Vec3d& win) const {return (project(v, win) && checkInViewport(win));}
00272
00277 bool projectCheck(const Vec3f& v, Vec3f& win) const {return (project(v, win) && checkInViewport(win));}
00278
00283 bool unProject(const Vec3d& win, Vec3d& v) const {return unProject(win[0], win[1], v);}
00284 bool unProject(double x, double y, Vec3d& v) const;
00285
00292 bool projectLineCheck(const Vec3d& v1, Vec3d& win1, const Vec3d& v2, Vec3d& win2) const
00293 {return project(v1, win1) && project(v2, win2) && (checkInViewport(win1) || checkInViewport(win2));}
00294
00296 const Mat4d& getModelViewMatrix() const {return modelViewMatrix;}
00297
00299 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);}
00300
00303 static const QString maskTypeToString(StelProjectorMaskType type);
00305 static StelProjectorMaskType stringToMaskType(const QString &s);
00306
00308 StelProjectorMaskType getMaskType(void) const {return maskType;}
00309
00310 protected:
00312 StelProjector(const Mat4d& modelViewMat) : modelViewMatrix(modelViewMat),
00313 modelViewMatrixf(modelViewMat[0], modelViewMat[1], modelViewMat[2], modelViewMat[3],
00314 modelViewMat[4], modelViewMat[5], modelViewMat[6], modelViewMat[7],
00315 modelViewMat[8], modelViewMat[9], modelViewMat[10], modelViewMat[11],
00316 modelViewMat[12], modelViewMat[13], modelViewMat[14], modelViewMat[15]) {;}
00318 virtual bool hasDiscontinuity() const =0;
00322 virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const = 0;
00323
00325 virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const = 0;
00326
00328 virtual void computeBoundingCap();
00329
00330 Mat4d modelViewMatrix;
00331 Mat4f modelViewMatrixf;
00332 float flipHorz,flipVert;
00333 float pixelPerRad;
00334 StelProjectorMaskType maskType;
00335 float zNear, oneOverZNearMinusZFar;
00336 Vec4i viewportXywh;
00337 Vec2f viewportCenter;
00338 float viewportFovDiameter;
00339 bool gravityLabels;
00340 SphericalCap boundingCap;
00341
00342 private:
00344 void init(const StelProjectorParams& param);
00345 };
00346
00347 #endif // _STELPROJECTOR_HPP_