Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/hud/src/orxonox/overlays/hud/HUDNavigation.cc @ 1616

Last change on this file since 1616 was 1616, checked in by rgrieder, 16 years ago
  • precompiled header files have disadvantages too…
  • Property svn:eol-style set to native
File size: 10.1 KB
RevLine 
[1505]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
[1454]4 *
[1505]5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
[1454]22 *   Author:
23 *      Felix Schulthess
24 *   Co-authors:
[1590]25 *      Reto Grieder
[1454]26 *
27 */
[1393]28
[1410]29#include "OrxonoxStableHeaders.h"
[1601]30#include "HUDNavigation.h"
[1410]31
[1393]32#include <OgreOverlayManager.h>
[1614]33#include <OgreTextAreaOverlayElement.h>
34#include <OgrePanelOverlayElement.h>
[1410]35
[1614]36#include "util/Math.h"
[1615]37#include "util/String.h"
[1616]38#include "util/Convert.h"
[1604]39#include "core/ConsoleCommand.h"
[1616]40#include "core/CoreIncludes.h"
41#include "core/XMLPort.h"
[1393]42#include "objects/SpaceShip.h"
[1566]43#include "objects/Projectile.h"
[1399]44#include "objects/CameraHandler.h"
[1613]45#include "Radar.h"
[1393]46
47namespace orxonox
48{
[1601]49    CreateFactory(HUDNavigation);
[1590]50
[1601]51    HUDNavigation::HUDNavigation()
[1615]52        : navMarker_(0)
53        , aimMarker_(0)
54        , navText_(0)
[1580]55    {
[1601]56        RegisterObject(HUDNavigation);
[1393]57    }
58
[1601]59    HUDNavigation::~HUDNavigation()
[1564]60    {
[1615]61        if (this->navMarker_)
62            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->navMarker_);
63        if (this->navText_)
64            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->navText_);
65        if (this->aimMarker_)
66            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->aimMarker_);
[1564]67    }
68
[1601]69    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
[1580]70    {
[1601]71        OrxonoxOverlay::XMLPort(xmlElement, mode);
[1394]72
[1590]73        if (mode == XMLPort::LoadObject)
74        {
75            // create nav text
[1615]76            navText_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
77                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberStr()));
[1595]78            navText_->setCharHeight(0.05f);
79            navText_->setFontName("Monofur");
[1590]80
81            // create nav marker
[1615]82            navMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
83                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberStr()));
[1590]84            navMarker_->setMaterialName("Orxonox/NavArrows");
[1604]85            navMarkerSize_ = 0.05; //default
86            wasOutOfView_ = true; // just to ensure the material is changed right the first time..
[1590]87
88            // create aim marker
[1615]89            aimMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
90                .createOverlayElement("Panel", "HUDNavigation_aimMarker_" + getUniqueNumberStr()));
[1590]91            aimMarker_->setMaterialName("Orxonox/NavCrosshair");
[1604]92            aimMarkerSize_ = 0.04; // default
[1590]93           
[1615]94            background_->addChild(navMarker_);
95            background_->addChild(aimMarker_);
96            background_->addChild(navText_);
[1590]97
[1615]98            // hide at first
99            this->setVisibility(false);
[1590]100        }
101
[1601]102        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlElement, mode);
103        XMLPortParam(HUDNavigation, "textsize", setTextSize, getTextSize, xmlElement, mode);
104        XMLPortParam(HUDNavigation, "navmarkersize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
105        XMLPortParam(HUDNavigation, "aimmarkersize", setAimMarkerSize, getAimMarkerSize, xmlElement, mode);
[1595]106
107        if (mode == XMLPort::LoadObject)
108        {
109            this->sizeChanged();
110        }
[1410]111    }
[1393]112
[1601]113    void HUDNavigation::setFont(const std::string& font)
[1590]114    {
115        if (this->navText_ && font != "")
116            this->navText_->setFontName(font);
117    }
118
[1615]119    const std::string& HUDNavigation::getFont() const
[1590]120    {
121        if (this->navText_)
122            return this->navText_->getFontName();
123        else
[1615]124            return blankString;
[1590]125    }
126
[1601]127    void HUDNavigation::setTextSize(float size)
[1590]128    {
129        if (this->navText_ && size >= 0.0f)
130            this->navText_->setCharHeight(size);
131    }
132
[1601]133    float HUDNavigation::getTextSize() const
[1590]134    {
135        if (this->navText_)
136            return this->navText_->getCharHeight();
137        else
138            return 0.0f;
139    }
140
[1601]141    void HUDNavigation::tick(float dt)
[1590]142    {
[1613]143        if (!Radar::getInstance().getFocus())
144        {
145            this->overlay_->hide();
[1564]146            return;
[1613]147        }
148        else
149        {
150            this->overlay_->show();
151        }
[1400]152
[1399]153        // set text
[1613]154        int dist = (int) getDist2Focus();
[1590]155        navText_->setCaption(convertToString(dist));
156        float textLength = convertToString(dist).size() * navText_->getCharHeight() * 0.3;
[1399]157
[1564]158        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
[1590]159        Matrix4 transformationMatrix = navCam->getProjectionMatrix() * navCam->getViewMatrix();
[1399]160        // transform to screen coordinates
[1613]161        Vector3 pos = transformationMatrix * Radar::getInstance().getFocus()->getWorldPosition();
[1564]162
[1590]163        bool outOfView;
164        if (pos.z > 1.0)
165        {
166            // z > 1.0 means that the object is behind the camera
[1580]167            outOfView = true;
[1590]168            // we have to switch all coordinates (if you don't know why,
169            // try linear algebra lectures, because I can't explain..)
170            pos.x = -pos.x;
171            pos.y = -pos.y;
172        }
173        else
174            outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
[1399]175
[1580]176        if (outOfView)
177        {
[1411]178            // object is not in view
[1566]179            aimMarker_->hide();
[1411]180
[1590]181            if (!wasOutOfView_)
[1580]182            {
[1590]183                navMarker_->setMaterialName("Orxonox/NavArrows");
184                wasOutOfView_ = true;
[1411]185            }
[1590]186
187            if (pos.x < pos.y)
[1580]188            {
[1590]189                if (pos.y > -pos.x)
[1580]190                {
[1590]191                    // up
192                    float position = pos.x / pos.y + 1.0;
193                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 0.0);
[1399]194                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
[1590]195                    navText_->setLeft((position - textLength) * 0.5);
[1399]196                    navText_->setTop(navMarker_->getHeight());
197                }
[1580]198                else
199                {
[1590]200                    // left
201                    float position = pos.y / pos.x + 1.0;
202                    navMarker_->setPosition(0.0, (position - navMarker_->getWidth()) * 0.5);
[1411]203                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
[1590]204                    navText_->setLeft(navMarker_->getWidth() + 0.01);
205                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
[1411]206                }
207            }
[1590]208            else
[1580]209            {
[1590]210                if (pos.y < -pos.x)
[1580]211                {
[1590]212                    // down
213                    float position = -pos.x / pos.y + 1.0;
214                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 1.0 - navMarker_->getHeight());
[1399]215                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
[1590]216                    navText_->setLeft((position - textLength) * 0.5);
217                    navText_->setTop(1.0 - navMarker_->getHeight() - navText_->getCharHeight());
[1399]218                }
[1580]219                else
220                {
[1590]221                    // right
222                    float position = -pos.y / pos.x + 1.0;
223                    navMarker_->setPosition(1.0 - navMarker_->getWidth(), (position - navMarker_->getHeight()) * 0.5);
224                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
225                    navText_->setLeft(1.0 - navMarker_->getWidth() - textLength - 0.01);
226                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
[1399]227                }
[1393]228            }
229        }
[1580]230        else
231        {
[1411]232            // object is in view
[1590]233
234            Vector3 aimpos = transformationMatrix * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(),
[1613]235                    Projectile::getSpeed(), Radar::getInstance().getFocus()->getWorldPosition(), Radar::getInstance().getFocus()->getOrientedVelocity());
[1590]236
237            if (wasOutOfView_)
238            {
239                navMarker_->setMaterialName("Orxonox/NavTDC");
240                wasOutOfView_ = false;
241            }
242
243            // object is in view
[1459]244            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
[1590]245            navMarker_->setLeft((pos.x + 1.0 - navMarker_->getWidth()) * 0.5);
246            navMarker_->setTop((-pos.y + 1.0 - navMarker_->getHeight()) * 0.5);
[1566]247
248            aimMarker_->show();
[1590]249            aimMarker_->setLeft((aimpos.x + 1.0 - aimMarker_->getWidth()) * 0.5);
250            aimMarker_->setTop((-aimpos.y + 1.0 - aimMarker_->getHeight()) * 0.5);
[1566]251
[1590]252            navText_->setLeft((pos.x + 1.0 + navMarker_->getWidth()) * 0.5);
253            navText_->setTop((-pos.y + 1.0 + navMarker_->getHeight()) * 0.5);
[1393]254        }
[1410]255    }
[1394]256
[1601]257    float HUDNavigation::getDist2Focus() const
[1580]258    {
[1613]259        if (Radar::getInstance().getFocus())
260            return (Radar::getInstance().getFocus()->getWorldPosition() - SpaceShip::getLocalShip()->getPosition()).length();
[1580]261        else
262            return 0;
[1410]263    }
[1590]264
[1604]265    /**
266    @brief Overridden method of OrxonoxOverlay. Usually the entire overlay
267           scales with scale(). Here we obviously have to adjust this.
268    */
[1601]269    void HUDNavigation::sizeChanged()
[1590]270    {
[1604]271        // use size to compensate for apspect ratio if enabled.
272        float xScale = this->getSize().x;
273        float yScale = this->getSize().y;
[1595]274        if (this->navMarker_)
275            navMarker_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
276        if (this->aimMarker_)
277            aimMarker_->setDimensions(aimMarkerSize_ * xScale, aimMarkerSize_ * yScale);
278        if (this->navText_)
279            navText_->setCharHeight(navText_->getCharHeight() * yScale);
[1590]280    }
[1393]281}
Note: See TracBrowser for help on using the repository browser.