Home · All Namespaces · All Classes · Functions · Coding Style · Scripting · Plugins · File Structure

core/StelProjector.hpp

00001 /*
00002  * Stellarium
00003  * Copyright (C) 2003 Fabien Chereau
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     // Methods which must be reimplemented by all instance of StelProjector
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     // Full projection methods
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         // very important: even when the projected point comes from an
00242         // invisible region of the sky (rval=false), we must finish
00243         // reprojecting, so that OpenGl can successfully eliminate
00244         // polygons by culling.
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         // very important: even when the projected point comes from an
00259         // invisible region of the sky (rval=false), we must finish
00260         // reprojecting, so that OpenGl can successfully eliminate
00261         // polygons by culling.
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;              // openGL MODELVIEW Matrix
00332     Mat4f modelViewMatrixf;             // openGL MODELVIEW Matrix
00333     float flipHorz,flipVert;            // Whether to flip in horizontal or vertical directions
00334     float pixelPerRad;                  // pixel per rad at the center of the viewport disk
00335     StelProjectorMaskType maskType;     // The current projector mask
00336     float zNear, oneOverZNearMinusZFar; // Near and far clipping planes
00337     Vec4i viewportXywh;                 // Viewport parameters
00338     Vec2f viewportCenter;               // Viewport center in screen pixel
00339     float viewportFovDiameter;          // diameter of the FOV disk in pixel
00340     bool gravityLabels;                 // should label text align with the horizon?
00341     float defautAngleForGravityText;    // a rotation angle to apply to gravity text (only if gravityLabels is set to false)
00342     SphericalCap boundingCap;           // Bounding cap of the whole viewport
00343 
00344 private:
00346     void init(const StelProjectorParams& param);
00347 };
00348 
00349 #endif // _STELPROJECTOR_HPP_