/* * Copyright (C) 2003 Fabien Chereau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "StelCore.hpp" #include "StelNavigator.hpp" #include "StelProjector.hpp" #include "StelProjectorClasses.hpp" #include "StelToneReproducer.hpp" #include "StelSkyDrawer.hpp" #include "StelApp.hpp" #include "StelUtils.hpp" #include "StelGeodesicGrid.hpp" #include "StelMovementMgr.hpp" #include "StelModuleMgr.hpp" #include "StelPainter.hpp" #include #include #include #include /************************************************************************* Constructor *************************************************************************/ StelCore::StelCore() : navigation(NULL), movementMgr(NULL), geodesicGrid(NULL), currentProjectionType(ProjectionStereographic) { toneConverter = new StelToneReproducer(); QSettings* conf = StelApp::getInstance().getSettings(); // Create and initialize the default projector params QString tmpstr = conf->value("projection/viewport").toString(); currentProjectorParams.maskType = StelProjector::stringToMaskType(tmpstr); const int viewport_width = conf->value("projection/viewport_width", currentProjectorParams.viewportXywh[2]).toInt(); const int viewport_height = conf->value("projection/viewport_height", currentProjectorParams.viewportXywh[3]).toInt(); const int viewport_x = conf->value("projection/viewport_x", 0).toInt(); const int viewport_y = conf->value("projection/viewport_y", 0).toInt(); currentProjectorParams.viewportXywh.set(viewport_x,viewport_y,viewport_width,viewport_height); const float viewportCenterX = conf->value("projection/viewport_center_x",0.5f*viewport_width).toFloat(); const float viewportCenterY = conf->value("projection/viewport_center_y",0.5f*viewport_height).toFloat(); currentProjectorParams.viewportCenter.set(viewportCenterX, viewportCenterY); currentProjectorParams.viewportFovDiameter = conf->value("projection/viewport_fov_diameter", qMin(viewport_width,viewport_height)).toFloat(); currentProjectorParams.flipHorz = conf->value("projection/flip_horz",false).toBool(); currentProjectorParams.flipVert = conf->value("projection/flip_vert",false).toBool(); currentProjectorParams.gravityLabels = conf->value("viewing/flag_gravity_labels").toBool(); } /************************************************************************* Destructor *************************************************************************/ StelCore::~StelCore() { delete navigation; navigation=NULL; delete toneConverter; toneConverter=NULL; delete geodesicGrid; geodesicGrid=NULL; delete skyDrawer; skyDrawer=NULL; } /************************************************************************* Load core data and initialize with default values *************************************************************************/ void StelCore::init() { QSettings* conf = StelApp::getInstance().getSettings(); // StelNavigator navigation = new StelNavigator(); navigation->init(); movementMgr = new StelMovementMgr(this); movementMgr->init(); currentProjectorParams.fov = movementMgr->getInitFov(); StelApp::getInstance().getModuleMgr().registerModule(movementMgr); QString tmpstr = conf->value("projection/type", "stereographic").toString(); setCurrentProjectionTypeKey(tmpstr); skyDrawer = new StelSkyDrawer(this); skyDrawer->init(); } // Get the shared instance of StelGeodesicGrid. // The returned instance is garanteed to allow for at least maxLevel levels const StelGeodesicGrid* StelCore::getGeodesicGrid(int maxLevel) const { if (geodesicGrid==NULL) { geodesicGrid = new StelGeodesicGrid(maxLevel); } else if (maxLevel>geodesicGrid->getMaxLevel()) { delete geodesicGrid; geodesicGrid = new StelGeodesicGrid(maxLevel); } return geodesicGrid; } StelProjectorP StelCore::getProjection2d() const { StelProjectorP prj(new StelProjector2d()); prj->init(currentProjectorParams); return prj; } // Get an instance of projector using the current display parameters from Navigation, StelMovementMgr // and using the given modelview matrix StelProjectorP StelCore::getProjection(const Mat4d& modelViewMat, ProjectionType projType) const { if (projType==1000) projType = currentProjectionType; StelProjectorP prj; switch (projType) { case ProjectionPerspective: prj = StelProjectorP(new StelProjectorPerspective(modelViewMat)); break; case ProjectionEqualArea: prj = StelProjectorP(new StelProjectorEqualArea(modelViewMat)); break; case ProjectionStereographic: prj = StelProjectorP(new StelProjectorStereographic(modelViewMat)); break; case ProjectionFisheye: prj = StelProjectorP(new StelProjectorFisheye(modelViewMat)); break; case ProjectionHammer: prj = StelProjectorP(new StelProjectorHammer(modelViewMat)); break; case ProjectionCylinder: prj = StelProjectorP(new StelProjectorCylinder(modelViewMat)); break; case ProjectionMercator: prj = StelProjectorP(new StelProjectorMercator(modelViewMat)); break; case ProjectionOrthographic: prj = StelProjectorP(new StelProjectorOrthographic(modelViewMat)); break; default: qWarning() << "Unknown projection type: " << (int)(projType) << "using ProjectionStereographic instead"; prj = StelProjectorP(new StelProjectorStereographic(modelViewMat)); Q_ASSERT(0); } prj->init(currentProjectorParams); return prj; } // Get an instance of projector using the current display parameters from Navigation, StelMovementMgr StelProjectorP StelCore::getProjection(FrameType frameType, ProjectionType projType) const { switch (frameType) { case FrameAltAz: return getProjection(navigation->getAltAzModelViewMat(), projType); case FrameHeliocentricEcliptic: return getProjection(navigation->getHeliocentricEclipticModelViewMat(), projType); case FrameObservercentricEcliptic: return getProjection(navigation->getObservercentricEclipticModelViewMat(), projType); case FrameEquinoxEqu: return getProjection(navigation->getEquinoxEquModelViewMat(), projType); case FrameJ2000: return getProjection(navigation->getJ2000ModelViewMat(), projType); case FrameGalactic: return getProjection(navigation->getGalacticModelViewMat(), projType); default: qDebug() << "Unknown reference frame type: " << (int)frameType << "."; } Q_ASSERT(0); return getProjection2d(); } // Handle the resizing of the window void StelCore::windowHasBeenResized(float x, float y, float width, float height) { // Maximize display when resized since it invalidates previous options anyway currentProjectorParams.viewportXywh.set(x, y, width, height); currentProjectorParams.viewportCenter.set(x+0.5*width, y+0.5*height); currentProjectorParams.viewportFovDiameter = qMin(width,height); } /************************************************************************* Update all the objects in function of the time *************************************************************************/ void StelCore::update(double deltaTime) { // Update the position of observation and time and recompute planet positions etc... navigation->updateTime(deltaTime); // Transform matrices between coordinates systems navigation->updateTransformMatrices(); // Update direction of vision/Zoom level movementMgr->updateMotion(deltaTime); currentProjectorParams.fov = movementMgr->getCurrentFov(); skyDrawer->update(deltaTime); } /************************************************************************* Execute all the pre-drawing functions *************************************************************************/ void StelCore::preDraw() { // Init openGL viewing with fov, screen size and clip planes currentProjectorParams.zNear = 0.000001; currentProjectorParams.zFar = 50.; skyDrawer->preDraw(); // Clear areas not redrawn by main viewport (i.e. fisheye square viewport) StelPainter sPainter(getProjection2d()); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); } /************************************************************************* Update core state after drawing modules *************************************************************************/ void StelCore::postDraw() { StelPainter sPainter(getProjection(StelCore::FrameJ2000)); sPainter.drawViewportShape(); } void StelCore::setCurrentProjectionType(ProjectionType type) { currentProjectionType=type; const double savedFov = currentProjectorParams.fov; currentProjectorParams.fov = 0.0001; // Avoid crash double newMaxFov = getProjection(Mat4d::identity())->getMaxFov(); movementMgr->setMaxFov(newMaxFov); currentProjectorParams.fov = qMin(newMaxFov, savedFov); } //! Set the current projection type to use void StelCore::setCurrentProjectionTypeKey(QString key) { const QMetaEnum& en = metaObject()->enumerator(metaObject()->indexOfEnumerator("ProjectionType")); ProjectionType newType = (ProjectionType)en.keyToValue(key.toAscii().data()); if (newType<0) { qWarning() << "Unknown projection type: " << key << "setting \"ProjectionStereographic\" instead"; newType = ProjectionStereographic; } setCurrentProjectionType(newType); } //! Get the current Mapping used by the Projection QString StelCore::getCurrentProjectionTypeKey(void) const { return metaObject()->enumerator(metaObject()->indexOfEnumerator("ProjectionType")).key(currentProjectionType); } //! Get the list of all the available projections QStringList StelCore::getAllProjectionTypeKeys() const { const QMetaEnum& en = metaObject()->enumerator(metaObject()->indexOfEnumerator("ProjectionType")); QStringList l; for (int i=0;ienumerator(metaObject()->indexOfEnumerator("ProjectionType")); QString s(getProjection(StelCore::FrameJ2000, (ProjectionType)en.keysToValue(key.toAscii()))->getNameI18()); return s; } //! Get the projection TypeKey from its translated name for the current locale QString StelCore::projectionNameI18nToTypeKey(const QString& nameI18n) const { const QMetaEnum& en = metaObject()->enumerator(metaObject()->indexOfEnumerator("ProjectionType")); for (int i=0;igetNameI18()==nameI18n) return en.valueToKey(i); } // Unknown translated name Q_ASSERT(0); return en.valueToKey(ProjectionStereographic); }