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
00040 class ModelViewTranform;
00043 typedef QSharedPointer<ModelViewTranform> ModelViewTranformP;
00044
00047 class ModelViewTranform
00048 {
00049 public:
00050 ModelViewTranform() {;}
00051 virtual ~ModelViewTranform() {;}
00052 virtual void forward(Vec3d&) const =0;
00053 virtual void backward(Vec3d&) const =0;
00054 virtual void forward(Vec3f&) const =0;
00055 virtual void backward(Vec3f&) const =0;
00056
00057 virtual void combine(const Mat4d&)=0;
00058 virtual ModelViewTranformP clone() const=0;
00059
00060 virtual Mat4d getApproximateLinearTransfo() const=0;
00061 };
00062
00063 class Mat4dTransform: public ModelViewTranform
00064 {
00065 public:
00066 Mat4dTransform(const Mat4d& m) : transfoMat(m),
00067 transfoMatf(m[0], m[1], m[2], m[3],
00068 m[4], m[5], m[6], m[7],
00069 m[8], m[9], m[10], m[11],
00070 m[12], m[13], m[14], m[15]) {;}
00071
00072 void forward(Vec3d& v) const {v.transfo4d(transfoMat);}
00073 void backward(Vec3d& v) const
00074 {
00075
00076
00077 const double x = v[0] - transfoMat.r[12];
00078 const double y = v[1] - transfoMat.r[13];
00079 const double z = v[2] - transfoMat.r[14];
00080 v[0] = transfoMat.r[0]*x + transfoMat.r[1]*y + transfoMat.r[2]*z;
00081 v[1] = transfoMat.r[4]*x + transfoMat.r[5]*y + transfoMat.r[6]*z;
00082 v[2] = transfoMat.r[8]*x + transfoMat.r[9]*y + transfoMat.r[10]*z;
00083 }
00084 void forward(Vec3f& v) const {v.transfo4d(transfoMatf);}
00085 void backward(Vec3f& v) const
00086 {
00087
00088
00089 const float x = v[0] - transfoMatf.r[12];
00090 const float y = v[1] - transfoMatf.r[13];
00091 const float z = v[2] - transfoMatf.r[14];
00092 v[0] = transfoMatf.r[0]*x + transfoMatf.r[1]*y + transfoMatf.r[2]*z;
00093 v[1] = transfoMatf.r[4]*x + transfoMatf.r[5]*y + transfoMatf.r[6]*z;
00094 v[2] = transfoMatf.r[8]*x + transfoMatf.r[9]*y + transfoMatf.r[10]*z;
00095 }
00096 void combine(const Mat4d& m)
00097 {
00098 Mat4f mf(m[0], m[1], m[2], m[3],
00099 m[4], m[5], m[6], m[7],
00100 m[8], m[9], m[10], m[11],
00101 m[12], m[13], m[14], m[15]);
00102 transfoMat=transfoMat*m;
00103 transfoMatf=transfoMatf*mf;
00104 }
00105 Mat4d getApproximateLinearTransfo() const {return transfoMat;}
00106 ModelViewTranformP clone() const {return ModelViewTranformP(new Mat4dTransform(transfoMat));}
00107
00108 private:
00110 Mat4d transfoMat;
00111 Mat4f transfoMatf;
00112 };
00113
00116 enum StelProjectorMaskType
00117 {
00118 MaskNone,
00119 MaskDisk
00120 };
00121
00124 struct StelProjectorParams
00125 {
00126 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) {;}
00127 Vector4<int> viewportXywh;
00128 float fov;
00129 bool gravityLabels;
00130 float defautAngleForGravityText;
00131 StelProjectorMaskType maskType;
00132 float zNear, zFar;
00133 Vec2f viewportCenter;
00134 float viewportFovDiameter;
00135 bool flipHorz, flipVert;
00136 };
00137
00139 virtual ~StelProjector() {}
00140
00142
00144 virtual QString getNameI18() const = 0;
00146 virtual QString getDescriptionI18() const {return "No description";}
00148 QString getHtmlSummary() const;
00150 virtual float getMaxFov() const = 0;
00157 virtual bool forward(Vec3f& v) const = 0;
00159 virtual bool backward(Vec3d& v) const = 0;
00161 virtual float deltaZoom(float fov) const = 0;
00162
00166 bool intersectViewportDiscontinuity(const Vec3d& p1, const Vec3d& p2) const
00167 {
00168 if (hasDiscontinuity()==false)
00169 return false;
00170 Vec3d v1(p1);
00171 modelViewTransform->forward(v1);
00172 Vec3d v2(p2);
00173 modelViewTransform->forward(v2);
00174 return intersectViewportDiscontinuityInternal(v1, v2);
00175 }
00176
00177 bool intersectViewportDiscontinuity(const SphericalCap& cap) const
00178 {
00179 if (hasDiscontinuity()==false)
00180 return false;
00181 Vec3d v1(cap.n);
00182 modelViewTransform->forward(v1);
00183 return intersectViewportDiscontinuityInternal(v1, cap.d);
00184 }
00185
00187 virtual float fovToViewScalingFactor(float fov) const = 0;
00189 virtual float viewScalingFactorToFov(float vsf) const = 0;
00190
00194 bool getFlagGravityLabels() const { return gravityLabels; }
00195
00197 const Vec4i& getViewport() const {return viewportXywh;}
00198
00200 Vec2f getViewportCenter() const
00201 {
00202 return Vec2f(viewportCenter[0]-viewportXywh[0],viewportCenter[1]-viewportXywh[1]);
00203 }
00204
00206 int getViewportPosX() const {return viewportXywh[0];}
00208 int getViewportPosY() const {return viewportXywh[1];}
00210 int getViewportWidth() const {return viewportXywh[2];}
00212 int getViewportHeight() const {return viewportXywh[3];}
00213
00219 SphericalRegionP getViewportConvexPolygon(float marginX=0., float marginY=0.) const;
00220
00222 const SphericalCap& getBoundingCap() const {return boundingCap;}
00223
00225 float getPixelPerRadAtCenter() const {return pixelPerRad;}
00226
00228 float getFov() const {return 360.f/M_PI*viewScalingFactorToFov(0.5f*viewportFovDiameter/pixelPerRad);}
00229
00231 bool needGlFrontFaceCW() const {return (flipHorz*flipVert < 0.f);}
00232
00234
00237 bool checkInViewport(const Vec3d& pos) const
00238 {
00239 return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
00240 pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(viewportXywh[0] + viewportXywh[2]));
00241 }
00242
00245 bool checkInViewport(const Vec3f& pos) const
00246 {
00247 return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
00248 pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(viewportXywh[0] + viewportXywh[2]));
00249 }
00250
00253 Vec3d viewPortIntersect(const Vec3d& p1, const Vec3d& p2) const
00254 {
00255 Vec3d v1=p1;
00256 Vec3d v2=p2;
00257 Vec3d v;
00258 for (int i=0;i<8;++i)
00259 {
00260 v=(v1+v2)*0.5;
00261 if (!checkInViewport(v))
00262 v2=v;
00263 else
00264 v1=v;
00265 }
00266 return v;
00267 }
00268
00273 inline bool project(const Vec3d& v, Vec3d& win) const
00274 {
00275 win = v;
00276 return projectInPlace(win);
00277 }
00278
00283 inline bool project(const Vec3f& v, Vec3f& win) const
00284 {
00285 win = v;
00286 return projectInPlace(win);
00287 }
00288
00289 virtual void project(int n, const Vec3d* in, Vec3f* out)
00290 {
00291 Vec3d v;
00292 for (int i = 0; i < n; ++i, ++out)
00293 {
00294 v = in[i];
00295 modelViewTransform->forward(v);
00296 out->set(v[0], v[1], v[2]);
00297 forward(*out);
00298 out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00299 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00300 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00301 }
00302 }
00303
00304 virtual void project(int n, const Vec3f* in, Vec3f* out)
00305 {
00306 for (int i = 0; i < n; ++i, ++out)
00307 {
00308 *out=in[i];
00309 modelViewTransform->forward(*out);
00310 forward(*out);
00311 out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00312 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00313 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00314 }
00315 }
00316
00320 inline bool projectInPlace(Vec3d& vd) const
00321 {
00322 modelViewTransform->forward(vd);
00323 Vec3f v(vd[0], vd[1], vd[2]);
00324 const bool rval = forward(v);
00325
00326
00327
00328
00329 vd[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
00330 vd[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
00331 vd[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
00332 return rval;
00333 }
00334
00338 inline bool projectInPlace(Vec3f& v) const
00339 {
00340 modelViewTransform->forward(v);
00341 const bool rval = forward(v);
00342
00343
00344
00345
00346 v[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
00347 v[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
00348 v[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
00349 return rval;
00350 }
00351
00356 bool projectCheck(const Vec3d& v, Vec3d& win) const {return (project(v, win) && checkInViewport(win));}
00357
00362 bool projectCheck(const Vec3f& v, Vec3f& win) const {return (project(v, win) && checkInViewport(win));}
00363
00368 bool unProject(const Vec3d& win, Vec3d& v) const {return unProject(win[0], win[1], v);}
00369 bool unProject(double x, double y, Vec3d& v) const;
00370
00377 bool projectLineCheck(const Vec3d& v1, Vec3d& win1, const Vec3d& v2, Vec3d& win2) const
00378 {return project(v1, win1) && project(v2, win2) && (checkInViewport(win1) || checkInViewport(win2));}
00379
00381 ModelViewTranformP getModelViewTransform() const {return modelViewTransform;}
00382
00384 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);}
00385
00388 static const QString maskTypeToString(StelProjectorMaskType type);
00390 static StelProjectorMaskType stringToMaskType(const QString &s);
00391
00393 StelProjectorMaskType getMaskType(void) const {return maskType;}
00394
00395 protected:
00397 StelProjector(ModelViewTranformP amodelViewTransform) : modelViewTransform(amodelViewTransform) {;}
00398
00400 virtual bool hasDiscontinuity() const =0;
00404 virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const = 0;
00405
00407 virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const = 0;
00408
00410 virtual void computeBoundingCap();
00411
00412 ModelViewTranformP modelViewTransform;
00413
00414 float flipHorz,flipVert;
00415 float pixelPerRad;
00416 StelProjectorMaskType maskType;
00417 float zNear, oneOverZNearMinusZFar;
00418 Vec4i viewportXywh;
00419 Vec2f viewportCenter;
00420 float viewportFovDiameter;
00421 bool gravityLabels;
00422 float defautAngleForGravityText;
00423 SphericalCap boundingCap;
00424
00425 private:
00427 void init(const StelProjectorParams& param);
00428 };
00429
00430 #endif // _STELPROJECTOR_HPP_