Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1615 was 1615, checked in by rgrieder, 16 years ago
  • added blankString to String so you can return ""; even if it's a const std::string&
  • fixed several bugs with aspect correct and margin alignment
  • added console commands for OrxonoxOverlays and OverlayGroups for rotate, scale and scroll (you can access the by name (from name=.. in xml file), e.g. "OrxonoxOverlay rotateOverlay SpeedBar 90)
  • converted everything in overlays/ to 4 spaces/tab ;)
  • removed all using namespace Ogre;
  • added background_ Panel to OrxonoxOverlay, since most of the derived classes can use that
  • should work now, but I'll have to test on a tardis box first
  • Property svn:eol-style set to native
File size: 10.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
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 *
22 *   Author:
23 *      Felix Schulthess
24 *   Co-authors:
25 *      Reto Grieder
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "HUDNavigation.h"
31
32#include <OgreOverlayManager.h>
33#include <OgreTextAreaOverlayElement.h>
34#include <OgrePanelOverlayElement.h>
35
36#include "util/Math.h"
37#include "util/String.h"
38#include "core/ConsoleCommand.h"
39#include "objects/SpaceShip.h"
40#include "objects/Projectile.h"
41#include "objects/CameraHandler.h"
42#include "Radar.h"
43
44namespace orxonox
45{
46    CreateFactory(HUDNavigation);
47
48    HUDNavigation::HUDNavigation()
49        : navMarker_(0)
50        , aimMarker_(0)
51        , navText_(0)
52    {
53        RegisterObject(HUDNavigation);
54    }
55
56    HUDNavigation::~HUDNavigation()
57    {
58        if (this->navMarker_)
59            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->navMarker_);
60        if (this->navText_)
61            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->navText_);
62        if (this->aimMarker_)
63            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->aimMarker_);
64    }
65
66    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
67    {
68        OrxonoxOverlay::XMLPort(xmlElement, mode);
69
70        if (mode == XMLPort::LoadObject)
71        {
72            // create nav text
73            navText_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
74                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberStr()));
75            navText_->setCharHeight(0.05f);
76            navText_->setFontName("Monofur");
77
78            // create nav marker
79            navMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
80                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberStr()));
81            navMarker_->setMaterialName("Orxonox/NavArrows");
82            navMarkerSize_ = 0.05; //default
83            wasOutOfView_ = true; // just to ensure the material is changed right the first time..
84
85            // create aim marker
86            aimMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
87                .createOverlayElement("Panel", "HUDNavigation_aimMarker_" + getUniqueNumberStr()));
88            aimMarker_->setMaterialName("Orxonox/NavCrosshair");
89            aimMarkerSize_ = 0.04; // default
90           
91            background_->addChild(navMarker_);
92            background_->addChild(aimMarker_);
93            background_->addChild(navText_);
94
95            // hide at first
96            this->setVisibility(false);
97        }
98
99        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlElement, mode);
100        XMLPortParam(HUDNavigation, "textsize", setTextSize, getTextSize, xmlElement, mode);
101        XMLPortParam(HUDNavigation, "navmarkersize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
102        XMLPortParam(HUDNavigation, "aimmarkersize", setAimMarkerSize, getAimMarkerSize, xmlElement, mode);
103
104        if (mode == XMLPort::LoadObject)
105        {
106            this->sizeChanged();
107        }
108    }
109
110    void HUDNavigation::setFont(const std::string& font)
111    {
112        if (this->navText_ && font != "")
113            this->navText_->setFontName(font);
114    }
115
116    const std::string& HUDNavigation::getFont() const
117    {
118        if (this->navText_)
119            return this->navText_->getFontName();
120        else
121            return blankString;
122    }
123
124    void HUDNavigation::setTextSize(float size)
125    {
126        if (this->navText_ && size >= 0.0f)
127            this->navText_->setCharHeight(size);
128    }
129
130    float HUDNavigation::getTextSize() const
131    {
132        if (this->navText_)
133            return this->navText_->getCharHeight();
134        else
135            return 0.0f;
136    }
137
138    void HUDNavigation::tick(float dt)
139    {
140        if (!Radar::getInstance().getFocus())
141        {
142            this->overlay_->hide();
143            return;
144        }
145        else
146        {
147            this->overlay_->show();
148        }
149
150        // set text
151        int dist = (int) getDist2Focus();
152        navText_->setCaption(convertToString(dist));
153        float textLength = convertToString(dist).size() * navText_->getCharHeight() * 0.3;
154
155        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
156        Matrix4 transformationMatrix = navCam->getProjectionMatrix() * navCam->getViewMatrix();
157        // transform to screen coordinates
158        Vector3 pos = transformationMatrix * Radar::getInstance().getFocus()->getWorldPosition();
159
160        bool outOfView;
161        if (pos.z > 1.0)
162        {
163            // z > 1.0 means that the object is behind the camera
164            outOfView = true;
165            // we have to switch all coordinates (if you don't know why,
166            // try linear algebra lectures, because I can't explain..)
167            pos.x = -pos.x;
168            pos.y = -pos.y;
169        }
170        else
171            outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
172
173        if (outOfView)
174        {
175            // object is not in view
176            aimMarker_->hide();
177
178            if (!wasOutOfView_)
179            {
180                navMarker_->setMaterialName("Orxonox/NavArrows");
181                wasOutOfView_ = true;
182            }
183
184            if (pos.x < pos.y)
185            {
186                if (pos.y > -pos.x)
187                {
188                    // up
189                    float position = pos.x / pos.y + 1.0;
190                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 0.0);
191                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
192                    navText_->setLeft((position - textLength) * 0.5);
193                    navText_->setTop(navMarker_->getHeight());
194                }
195                else
196                {
197                    // left
198                    float position = pos.y / pos.x + 1.0;
199                    navMarker_->setPosition(0.0, (position - navMarker_->getWidth()) * 0.5);
200                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
201                    navText_->setLeft(navMarker_->getWidth() + 0.01);
202                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
203                }
204            }
205            else
206            {
207                if (pos.y < -pos.x)
208                {
209                    // down
210                    float position = -pos.x / pos.y + 1.0;
211                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 1.0 - navMarker_->getHeight());
212                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
213                    navText_->setLeft((position - textLength) * 0.5);
214                    navText_->setTop(1.0 - navMarker_->getHeight() - navText_->getCharHeight());
215                }
216                else
217                {
218                    // right
219                    float position = -pos.y / pos.x + 1.0;
220                    navMarker_->setPosition(1.0 - navMarker_->getWidth(), (position - navMarker_->getHeight()) * 0.5);
221                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
222                    navText_->setLeft(1.0 - navMarker_->getWidth() - textLength - 0.01);
223                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
224                }
225            }
226        }
227        else
228        {
229            // object is in view
230
231            Vector3 aimpos = transformationMatrix * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(),
232                    Projectile::getSpeed(), Radar::getInstance().getFocus()->getWorldPosition(), Radar::getInstance().getFocus()->getOrientedVelocity());
233
234            if (wasOutOfView_)
235            {
236                navMarker_->setMaterialName("Orxonox/NavTDC");
237                wasOutOfView_ = false;
238            }
239
240            // object is in view
241            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
242            navMarker_->setLeft((pos.x + 1.0 - navMarker_->getWidth()) * 0.5);
243            navMarker_->setTop((-pos.y + 1.0 - navMarker_->getHeight()) * 0.5);
244
245            aimMarker_->show();
246            aimMarker_->setLeft((aimpos.x + 1.0 - aimMarker_->getWidth()) * 0.5);
247            aimMarker_->setTop((-aimpos.y + 1.0 - aimMarker_->getHeight()) * 0.5);
248
249            navText_->setLeft((pos.x + 1.0 + navMarker_->getWidth()) * 0.5);
250            navText_->setTop((-pos.y + 1.0 + navMarker_->getHeight()) * 0.5);
251        }
252    }
253
254    float HUDNavigation::getDist2Focus() const
255    {
256        if (Radar::getInstance().getFocus())
257            return (Radar::getInstance().getFocus()->getWorldPosition() - SpaceShip::getLocalShip()->getPosition()).length();
258        else
259            return 0;
260    }
261
262    /**
263    @brief Overridden method of OrxonoxOverlay. Usually the entire overlay
264           scales with scale(). Here we obviously have to adjust this.
265    */
266    void HUDNavigation::sizeChanged()
267    {
268        // use size to compensate for apspect ratio if enabled.
269        float xScale = this->getSize().x;
270        float yScale = this->getSize().y;
271        if (this->navMarker_)
272            navMarker_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
273        if (this->aimMarker_)
274            aimMarker_->setDimensions(aimMarkerSize_ * xScale, aimMarkerSize_ * yScale);
275        if (this->navText_)
276            navText_->setCharHeight(navText_->getCharHeight() * yScale);
277    }
278}
Note: See TracBrowser for help on using the repository browser.