Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1614 was 1614, checked in by rgrieder, 16 years ago
  • Dots on the Radar actually disappear now when a Ship gets destroyed…
  • svn save to keep History of HUDText when renaming AND moving
  • Property svn:eol-style set to native
File size: 11.0 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"
[1604]37#include "core/ConsoleCommand.h"
[1393]38#include "objects/SpaceShip.h"
[1566]39#include "objects/Projectile.h"
[1399]40#include "objects/CameraHandler.h"
[1613]41#include "Radar.h"
[1393]42
43namespace orxonox
44{
[1601]45    CreateFactory(HUDNavigation);
[1590]46
[1613]47    //HUDNavigation* HUDNavigation::instance_s = 0;
[1604]48
[1393]49    using namespace Ogre;
50
[1601]51    HUDNavigation::HUDNavigation()
[1590]52      : container_(0)
53      , navMarker_(0)
54      , aimMarker_(0)
[1595]55      , navText_(0)
[1580]56    {
[1601]57        RegisterObject(HUDNavigation);
[1604]58       
[1613]59        /*assert(instance_s == 0); // singleton class
60        HUDNavigation::instance_s = this;*/
[1393]61    }
62
[1601]63    HUDNavigation::~HUDNavigation()
[1564]64    {
[1590]65        if (this->isInitialized())
66        {
67            if (this->navMarker_)
68                OverlayManager::getSingleton().destroyOverlayElement(this->navMarker_);
69            if (this->navText_)
70                OverlayManager::getSingleton().destroyOverlayElement(this->navText_);
71            if (this->aimMarker_)
72                OverlayManager::getSingleton().destroyOverlayElement(this->aimMarker_);
[1614]73            if (this->container_)
74                OverlayManager::getSingleton().destroyOverlayElement(this->container_);
[1590]75        }
[1604]76
[1613]77        //HUDNavigation::instance_s = 0;
[1564]78    }
79
[1601]80    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
[1580]81    {
[1601]82        OrxonoxOverlay::XMLPort(xmlElement, mode);
[1394]83
[1590]84        if (mode == XMLPort::LoadObject)
85        {
[1614]86            // create container because we cannot add a Text element to an Overlay
[1595]87            container_ = static_cast<OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", getName() + "_navContainer"));
[1394]88
[1590]89            // create nav text
[1595]90            navText_ = static_cast<TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", getName() + "_navText"));
91            navText_->setCharHeight(0.05f);
92            navText_->setFontName("Monofur");
[1590]93
94            // create nav marker
95            navMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", getName() + "_navMarker"));
96            navMarker_->setMaterialName("Orxonox/NavArrows");
[1604]97            navMarkerSize_ = 0.05; //default
98            wasOutOfView_ = true; // just to ensure the material is changed right the first time..
[1590]99
100            // create aim marker
101            aimMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", getName() + "_aimMarker"));
102            aimMarker_->setMaterialName("Orxonox/NavCrosshair");
[1604]103            aimMarkerSize_ = 0.04; // default
[1590]104           
105            container_->addChild(navMarker_);
106            container_->addChild(aimMarker_);
107            container_->addChild(navText_);
108            container_->show();
109
[1604]110            overlay_->add2D(container_);
[1590]111        }
112
[1601]113        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlElement, mode);
114        XMLPortParam(HUDNavigation, "textsize", setTextSize, getTextSize, xmlElement, mode);
115        XMLPortParam(HUDNavigation, "navmarkersize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
116        XMLPortParam(HUDNavigation, "aimmarkersize", setAimMarkerSize, getAimMarkerSize, xmlElement, mode);
[1595]117
118        if (mode == XMLPort::LoadObject)
119        {
120            this->sizeChanged();
121        }
[1410]122    }
[1393]123
[1601]124    void HUDNavigation::setNavMarkerSize(float size)
[1580]125    {
[1595]126        this->navMarkerSize_ = size;
[1590]127    }
128
[1601]129    float HUDNavigation::getNavMarkerSize() const
[1590]130    {
[1595]131        return this->navMarkerSize_;
[1590]132    }
133
[1601]134    void HUDNavigation::setAimMarkerSize(float size)
[1590]135    {
[1595]136        this->aimMarkerSize_ = size;
[1590]137    }
138
[1601]139    float HUDNavigation::getAimMarkerSize() const
[1590]140    {
[1595]141        return this->aimMarkerSize_;
[1590]142    }
143
[1601]144    void HUDNavigation::setFont(const std::string& font)
[1590]145    {
146        if (this->navText_ && font != "")
147            this->navText_->setFontName(font);
148    }
149
[1601]150    std::string HUDNavigation::getFont() const
[1590]151    {
152        if (this->navText_)
153            return this->navText_->getFontName();
154        else
155            return "";
156    }
157
[1601]158    void HUDNavigation::setTextSize(float size)
[1590]159    {
160        if (this->navText_ && size >= 0.0f)
161            this->navText_->setCharHeight(size);
162    }
163
[1601]164    float HUDNavigation::getTextSize() const
[1590]165    {
166        if (this->navText_)
167            return this->navText_->getCharHeight();
168        else
169            return 0.0f;
170    }
171
[1601]172    void HUDNavigation::tick(float dt)
[1590]173    {
[1613]174        if (!Radar::getInstance().getFocus())
175        {
176            this->overlay_->hide();
[1564]177            return;
[1613]178        }
179        else
180        {
181            this->overlay_->show();
182        }
[1400]183
[1399]184        // set text
[1613]185        int dist = (int) getDist2Focus();
[1590]186        navText_->setCaption(convertToString(dist));
187        float textLength = convertToString(dist).size() * navText_->getCharHeight() * 0.3;
[1399]188
[1564]189        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
[1590]190        Matrix4 transformationMatrix = navCam->getProjectionMatrix() * navCam->getViewMatrix();
[1399]191        // transform to screen coordinates
[1613]192        Vector3 pos = transformationMatrix * Radar::getInstance().getFocus()->getWorldPosition();
[1564]193
[1590]194        bool outOfView;
195        if (pos.z > 1.0)
196        {
197            // z > 1.0 means that the object is behind the camera
[1580]198            outOfView = true;
[1590]199            // we have to switch all coordinates (if you don't know why,
200            // try linear algebra lectures, because I can't explain..)
201            pos.x = -pos.x;
202            pos.y = -pos.y;
203        }
204        else
205            outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
[1399]206
[1580]207        if (outOfView)
208        {
[1411]209            // object is not in view
[1566]210            aimMarker_->hide();
[1411]211
[1590]212            if (!wasOutOfView_)
[1580]213            {
[1590]214                navMarker_->setMaterialName("Orxonox/NavArrows");
215                wasOutOfView_ = true;
[1411]216            }
[1590]217
218            if (pos.x < pos.y)
[1580]219            {
[1590]220                if (pos.y > -pos.x)
[1580]221                {
[1590]222                    // up
223                    float position = pos.x / pos.y + 1.0;
224                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 0.0);
[1399]225                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
[1590]226                    navText_->setLeft((position - textLength) * 0.5);
[1399]227                    navText_->setTop(navMarker_->getHeight());
228                }
[1580]229                else
230                {
[1590]231                    // left
232                    float position = pos.y / pos.x + 1.0;
233                    navMarker_->setPosition(0.0, (position - navMarker_->getWidth()) * 0.5);
[1411]234                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
[1590]235                    navText_->setLeft(navMarker_->getWidth() + 0.01);
236                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
[1411]237                }
238            }
[1590]239            else
[1580]240            {
[1590]241                if (pos.y < -pos.x)
[1580]242                {
[1590]243                    // down
244                    float position = -pos.x / pos.y + 1.0;
245                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 1.0 - navMarker_->getHeight());
[1399]246                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
[1590]247                    navText_->setLeft((position - textLength) * 0.5);
248                    navText_->setTop(1.0 - navMarker_->getHeight() - navText_->getCharHeight());
[1399]249                }
[1580]250                else
251                {
[1590]252                    // right
253                    float position = -pos.y / pos.x + 1.0;
254                    navMarker_->setPosition(1.0 - navMarker_->getWidth(), (position - navMarker_->getHeight()) * 0.5);
255                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
256                    navText_->setLeft(1.0 - navMarker_->getWidth() - textLength - 0.01);
257                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
[1399]258                }
[1393]259            }
260        }
[1580]261        else
262        {
[1411]263            // object is in view
[1590]264
265            Vector3 aimpos = transformationMatrix * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(),
[1613]266                    Projectile::getSpeed(), Radar::getInstance().getFocus()->getWorldPosition(), Radar::getInstance().getFocus()->getOrientedVelocity());
[1590]267
268            if (wasOutOfView_)
269            {
270                navMarker_->setMaterialName("Orxonox/NavTDC");
271                wasOutOfView_ = false;
272            }
273
274            // object is in view
[1459]275            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
[1590]276            navMarker_->setLeft((pos.x + 1.0 - navMarker_->getWidth()) * 0.5);
277            navMarker_->setTop((-pos.y + 1.0 - navMarker_->getHeight()) * 0.5);
[1566]278
279            aimMarker_->show();
[1590]280            aimMarker_->setLeft((aimpos.x + 1.0 - aimMarker_->getWidth()) * 0.5);
281            aimMarker_->setTop((-aimpos.y + 1.0 - aimMarker_->getHeight()) * 0.5);
[1566]282
[1590]283            navText_->setLeft((pos.x + 1.0 + navMarker_->getWidth()) * 0.5);
284            navText_->setTop((-pos.y + 1.0 + navMarker_->getHeight()) * 0.5);
[1393]285        }
[1410]286    }
[1394]287
[1601]288    float HUDNavigation::getDist2Focus() const
[1580]289    {
[1613]290        if (Radar::getInstance().getFocus())
291            return (Radar::getInstance().getFocus()->getWorldPosition() - SpaceShip::getLocalShip()->getPosition()).length();
[1580]292        else
293            return 0;
[1410]294    }
[1590]295
[1604]296    /**
297    @brief Overridden method of OrxonoxOverlay. Usually the entire overlay
298           scales with scale(). Here we obviously have to adjust this.
299    */
[1601]300    void HUDNavigation::sizeChanged()
[1590]301    {
[1604]302        // use size to compensate for apspect ratio if enabled.
303        float xScale = this->getSize().x;
304        float yScale = this->getSize().y;
[1595]305        if (this->navMarker_)
306            navMarker_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
307        if (this->aimMarker_)
308            aimMarker_->setDimensions(aimMarkerSize_ * xScale, aimMarkerSize_ * yScale);
309        if (this->navText_)
310            navText_->setCharHeight(navText_->getCharHeight() * yScale);
[1590]311    }
[1604]312
[1613]313    /*static*/ /*HUDNavigation& HUDNavigation::getInstance()
[1604]314    {
315        assert(instance_s);
316        return *instance_s;
[1613]317    }*/
[1393]318}
Note: See TracBrowser for help on using the repository browser.