StelProjector.cpp   StelProjector.cpp 
/* /*
* Stellarium * Stellarium
* Copyright (C) 2003 Fabien Chereau * Copyright (C) 2003 Fabien Chereau
* Copyright (C) 2012 Matthew Gates
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
skipping to change at line 28 skipping to change at line 29
*/ */
#include "StelTranslator.hpp" #include "StelTranslator.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "StelProjectorClasses.hpp" #include "StelProjectorClasses.hpp"
#include <QDebug> #include <QDebug>
#include <QString> #include <QString>
StelProjector::Mat4dTransform::Mat4dTransform(const Mat4d& m)
: transfoMat(m),
transfoMatf(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9
], m[10], m[11], m[12], m[13], m[14], m[15])
{
Q_ASSERT(m[0]==m[0]); // prelude to assert later in Atmosphere rende
ring... still investigating
}
void StelProjector::Mat4dTransform::forward(Vec3d& v) const
{
v.transfo4d(transfoMat);
}
void StelProjector::Mat4dTransform::backward(Vec3d& v) const
{
// We need no matrix inversion because we always work with orthogona
l matrices (where the transposed is the inverse).
//v.transfo4d(inverseTransfoMat);
const double x = v[0] - transfoMat.r[12];
const double y = v[1] - transfoMat.r[13];
const double z = v[2] - transfoMat.r[14];
v[0] = transfoMat.r[0]*x + transfoMat.r[1]*y + transfoMat.r[2]*z;
v[1] = transfoMat.r[4]*x + transfoMat.r[5]*y + transfoMat.r[6]*z;
v[2] = transfoMat.r[8]*x + transfoMat.r[9]*y + transfoMat.r[10]*z;
}
void StelProjector::Mat4dTransform::forward(Vec3f& v) const
{
v.transfo4d(transfoMatf);
}
void StelProjector::Mat4dTransform::backward(Vec3f& v) const
{
// We need no matrix inversion because we always work with orthogona
l matrices (where the transposed is the inverse).
//v.transfo4d(inverseTransfoMat);
const float x = v[0] - transfoMatf.r[12];
const float y = v[1] - transfoMatf.r[13];
const float z = v[2] - transfoMatf.r[14];
v[0] = transfoMatf.r[0]*x + transfoMatf.r[1]*y + transfoMatf.r[2]*z;
v[1] = transfoMatf.r[4]*x + transfoMatf.r[5]*y + transfoMatf.r[6]*z;
v[2] = transfoMatf.r[8]*x + transfoMatf.r[9]*y + transfoMatf.r[10]*z
;
}
void StelProjector::Mat4dTransform::combine(const Mat4d& m)
{
Mat4f mf(m[0], m[1] , m[2], m[3],
m[4], m[5], m[6], m[7],
m[8], m[9], m[10], m[11],
m[12], m[13], m[14], m[15]);
transfoMat=transfoMat*m;
transfoMatf=transfoMatf*mf;
}
Mat4d StelProjector::Mat4dTransform::getApproximateLinearTransfo() const
{
return transfoMat;
}
StelProjector::ModelViewTranformP StelProjector::Mat4dTransform::clone() co
nst
{
return ModelViewTranformP(new Mat4dTransform(transfoMat));
}
const QString StelProjector::maskTypeToString(StelProjectorMaskType type) const QString StelProjector::maskTypeToString(StelProjectorMaskType type)
{ {
if (type == MaskDisk ) if (type == MaskDisk )
return "disk"; return "disk";
else else
return "none"; return "none";
} }
StelProjector::StelProjectorMaskType StelProjector::stringToMaskType(const QString &s) StelProjector::StelProjectorMaskType StelProjector::stringToMaskType(const QString &s)
{ {
skipping to change at line 64 skipping to change at line 126
viewportFovDiameter = params.viewportFovDiameter; viewportFovDiameter = params.viewportFovDiameter;
pixelPerRad = 0.5f * viewportFovDiameter / fovToViewScalingFactor(pa rams.fov*(M_PI/360.f)); pixelPerRad = 0.5f * viewportFovDiameter / fovToViewScalingFactor(pa rams.fov*(M_PI/360.f));
computeBoundingCap(); computeBoundingCap();
} }
QString StelProjector::getHtmlSummary() const QString StelProjector::getHtmlSummary() const
{ {
return QString("<h3>%1</h3><p>%2</p><b>%3</b>%4").arg(getNameI18()). arg(getDescriptionI18()).arg(q_("Maximum FOV: ")).arg(getMaxFov())+QChar(0x 00B0); return QString("<h3>%1</h3><p>%2</p><b>%3</b>%4").arg(getNameI18()). arg(getDescriptionI18()).arg(q_("Maximum FOV: ")).arg(getMaxFov())+QChar(0x 00B0);
} }
bool StelProjector::intersectViewportDiscontinuity(const Vec3d& p1, const V
ec3d& p2) const
{
if (hasDiscontinuity()==false)
return false;
Vec3d v1(p1);
modelViewTransform->forward(v1);
Vec3d v2(p2);
modelViewTransform->forward(v2);
return intersectViewportDiscontinuityInternal(v1, v2);
}
bool StelProjector::intersectViewportDiscontinuity(const SphericalCap& cap)
const
{
if (hasDiscontinuity()==false)
return false;
Vec3d v1(cap.n);
modelViewTransform->forward(v1);
return intersectViewportDiscontinuityInternal(v1, cap.d);
}
bool StelProjector::getFlagGravityLabels() const
{
return gravityLabels;
}
const Vec4i& StelProjector::getViewport() const
{
return viewportXywh;
}
Vec2f StelProjector::getViewportCenter() const
{
return Vec2f(viewportCenter[0]-viewportXywh[0],viewportCenter[1]-vie
wportXywh[1]);
}
int StelProjector::getViewportPosX() const
{
return viewportXywh[0];
}
int StelProjector::getViewportPosY() const
{
return viewportXywh[1];
}
int StelProjector::getViewportWidth() const
{
return viewportXywh[2];
}
int StelProjector::getViewportHeight() const
{
return viewportXywh[3];
}
/************************************************************************* /*************************************************************************
Return a convex polygon on the sphere which includes the viewport in the Return a convex polygon on the sphere which includes the viewport in the
current frame current frame
*************************************************************************/ *************************************************************************/
SphericalRegionP StelProjector::getViewportConvexPolygon(float marginX, flo at marginY) const SphericalRegionP StelProjector::getViewportConvexPolygon(float marginX, flo at marginY) const
{ {
Vec3d e0, e1, e2, e3; Vec3d e0, e1, e2, e3;
const Vec4i& vp = viewportXywh; const Vec4i& vp = viewportXywh;
bool ok = unProject(vp[0]-marginX,vp[1]-marginY,e0); bool ok = unProject(vp[0]-marginX,vp[1]-marginY,e0);
ok &= unProject(vp[0]+vp[2]+marginX,vp[1]-marginY,e1); ok &= unProject(vp[0]+vp[2]+marginX,vp[1]-marginY,e1);
skipping to change at line 111 skipping to change at line 228
return SphericalRegionP(res); return SphericalRegionP(res);
} }
//qDebug() << "!valid"; //qDebug() << "!valid";
delete res; delete res;
} }
//return SphericalRegionP((SphericalRegion*)(new AllSkySphericalRegi on())); //return SphericalRegionP((SphericalRegion*)(new AllSkySphericalRegi on()));
const SphericalCap& hp = getBoundingCap(); const SphericalCap& hp = getBoundingCap();
return SphericalRegionP(new SphericalCap(hp)); return SphericalRegionP(new SphericalCap(hp));
} }
const SphericalCap& StelProjector::getBoundingCap() const
{
return boundingCap;
}
float StelProjector::getPixelPerRadAtCenter() const
{
return pixelPerRad;
}
//! Get the current FOV diameter in degrees
float StelProjector::getFov() const {
return 360.f/M_PI*viewScalingFactorToFov(0.5f*viewportFovDiameter/pi
xelPerRad);
}
//! Get whether front faces need to be oriented in the clockwise direction
bool StelProjector::needGlFrontFaceCW() const
{
return (flipHorz*flipVert < 0.f);
}
bool StelProjector::checkInViewport(const Vec3d& pos) const
{
return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(view
portXywh[0] + viewportXywh[2]));
}
//! Check to see if a 2d position is inside the viewport.
//! TODO Optimize by storing viewportXywh[1] + viewportXywh[3] and viewport
Xywh[0] + viewportXywh[2] already computed
bool StelProjector::checkInViewport(const Vec3f& pos) const
{
return (pos[1]>=viewportXywh[1] && pos[0]>=viewportXywh[0] &&
pos[1]<=(viewportXywh[1] + viewportXywh[3]) && pos[0]<=(view
portXywh[0] + viewportXywh[2]));
}
//! Return the position where the 2 2D point p1 and p2 cross the viewport e
dge
//! P1 must be inside the viewport and P2 outside (check with checkInViewpo
rt() before calling this method)
Vec3d StelProjector::viewPortIntersect(const Vec3d& p1, const Vec3d& p2) co
nst
{
Vec3d v1=p1;
Vec3d v2=p2;
Vec3d v;
for (int i=0;i<8;++i)
{
v=(v1+v2)*0.5;
if (!checkInViewport(v))
v2=v;
else
v1=v;
}
return v;
}
bool StelProjector::project(const Vec3d& v, Vec3d& win) const
{
win = v;
return projectInPlace(win);
}
bool StelProjector::project(const Vec3f& v, Vec3f& win) const
{
win = v;
return projectInPlace(win);
}
void StelProjector::project(int n, const Vec3d* in, Vec3f* out)
{
Vec3d v;
for (int i = 0; i < n; ++i, ++out)
{
v = in[i];
modelViewTransform->forward(v);
out->set(v[0], v[1], v[2]);
forward(*out);
out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)
[0],
viewportCenter[1] + flipVert * pixelPerRad * (*out)[
1],
((*out)[2] - zNear) * oneOverZNearMinusZFar);
}
}
void StelProjector::project(int n, const Vec3f* in, Vec3f* out)
{
for (int i = 0; i < n; ++i, ++out)
{
*out=in[i];
modelViewTransform->forward(*out);
forward(*out);
out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)
[0],
viewportCenter[1] + flipVert * pixelPerRad * (*out)[
1],
((*out)[2] - zNear) * oneOverZNearMinusZFar);
}
}
bool StelProjector::projectInPlace(Vec3d& vd) const
{
modelViewTransform->forward(vd);
Vec3f v(vd[0], vd[1], vd[2]);
const bool rval = forward(v);
// very important: even when the projected point comes from an
// invisible region of the sky (rval=false), we must finish
// reprojecting, so that OpenGl can successfully eliminate
// polygons by culling.
vd[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
vd[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
vd[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
return rval;
}
bool StelProjector::projectInPlace(Vec3f& v) const
{
modelViewTransform->forward(v);
const bool rval = forward(v);
// very important: even when the projected point comes from an
// invisible region of the sky (rval=false), we must finish
// reprojecting, so that OpenGl can successfully eliminate
// polygons by culling.
v[0] = viewportCenter[0] + flipHorz * pixelPerRad * v[0];
v[1] = viewportCenter[1] + flipVert * pixelPerRad * v[1];
v[2] = (v[2] - zNear) * oneOverZNearMinusZFar;
return rval;
}
//! Project the vector v from the current frame into the viewport.
//! @param v the direction vector in the current frame. Does not need to be
normalized.
//! @param win the projected vector in the viewport 2D frame. win[0] and wi
n[1] are in screen pixels, win[2] is unused.
//! @return true if the projected point is inside the viewport.
bool StelProjector::projectCheck(const Vec3d& v, Vec3d& win) const
{
return (project(v, win) && checkInViewport(win));
}
//! Project the vector v from the current frame into the viewport.
//! @param v the direction vector in the current frame. Does not need to be
normalized.
//! @param win the projected vector in the viewport 2D frame. win[0] and wi
n[1] are in screen pixels, win[2] is unused.
//! @return true if the projected point is inside the viewport.
bool StelProjector::projectCheck(const Vec3f& v, Vec3f& win) const
{
return (project(v, win) && checkInViewport(win));
}
//! Project the vector v from the viewport frame into the current frame.
//! @param win the vector in the viewport 2D frame. win[0] and win[1] are i
n screen pixels, win[2] is unused.
//! @param v the unprojected direction vector in the current frame.
//! @return true if the projected coordinate is valid.
bool StelProjector::unProject(const Vec3d& win, Vec3d& v) const
{
return unProject(win[0], win[1], v);
}
void StelProjector::computeBoundingCap() void StelProjector::computeBoundingCap()
{ {
bool ok = unProject(viewportXywh[0]+0.5f*viewportXywh[2], viewportXy wh[1]+0.5f*viewportXywh[3], boundingCap.n); bool ok = unProject(viewportXywh[0]+0.5f*viewportXywh[2], viewportXy wh[1]+0.5f*viewportXywh[3], boundingCap.n);
Q_ASSERT(ok); // The central point should be at a valid position b y definition Q_ASSERT(ok); // The central point should be at a valid position b y definition
const bool needNormalization = fabs(boundingCap.n.lengthSquared()-1. )>0.00000001; const bool needNormalization = fabs(boundingCap.n.lengthSquared()-1. )>0.00000001;
// Now need to determine the aperture // Now need to determine the aperture
Vec3d e0,e1,e2,e3,e4,e5; Vec3d e0,e1,e2,e3,e4,e5;
const Vec4i& vp = viewportXywh; const Vec4i& vp = viewportXywh;
ok &= unProject(vp[0],vp[1],e0); ok &= unProject(vp[0],vp[1],e0);
skipping to change at line 159 skipping to change at line 425
boundingCap.d=h; boundingCap.d=h;
h = boundingCap.n*e3; h = boundingCap.n*e3;
if (boundingCap.d > h) if (boundingCap.d > h)
boundingCap.d=h; boundingCap.d=h;
h = boundingCap.n*e4; h = boundingCap.n*e4;
if (boundingCap.d > h) if (boundingCap.d > h)
boundingCap.d=h; boundingCap.d=h;
h = boundingCap.n*e5; h = boundingCap.n*e5;
if (boundingCap.d > h) if (boundingCap.d > h)
boundingCap.d=h; boundingCap.d=h;
} }
/************************************************************************* /*************************************************************************
Project the vector v from the viewport frame into the current frame Project the vector v from the viewport frame into the current frame
*************************************************************************/ *************************************************************************/
bool StelProjector::unProject(double x, double y, Vec3d &v) const bool StelProjector::unProject(double x, double y, Vec3d &v) const
{ {
v[0] = flipHorz * (x - viewportCenter[0]) / pixelPerRad; v[0] = flipHorz * (x - viewportCenter[0]) / pixelPerRad;
v[1] = flipVert * (y - viewportCenter[1]) / pixelPerRad; v[1] = flipVert * (y - viewportCenter[1]) / pixelPerRad;
v[2] = 0; v[2] = 0;
const bool rval = backward(v); const bool rval = backward(v);
// Even when the reprojected point comes from a region of the screen , // Even when the reprojected point comes from a region of the screen ,
// where nothing is projected to (rval=false), we finish reprojectin g. // where nothing is projected to (rval=false), we finish reprojectin g.
// This looks good for atmosphere rendering, and it helps avoiding // This looks good for atmosphere rendering, and it helps avoiding
// discontinuities when dragging around with the mouse. // discontinuities when dragging around with the mouse.
modelViewTransform->backward(v); modelViewTransform->backward(v);
return rval; return rval;
} }
bool StelProjector::projectLineCheck(const Vec3d& v1, Vec3d& win1, const Ve
c3d& v2, Vec3d& win2) const
{
return project(v1, win1) && project(v2, win2) && (checkInViewport(wi
n1) || checkInViewport(win2));
}
//! Get the current model view matrix.
StelProjector::ModelViewTranformP StelProjector::getModelViewTransform() co
nst
{
return modelViewTransform;
}
//! Get the current projection matrix.
Mat4f StelProjector::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);
}
StelProjector::StelProjectorMaskType StelProjector::getMaskType(void) const
{
return maskType;
}
 End of changes. 6 change blocks. 
0 lines changed or deleted 292 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/