Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/overlays/hud/HUDNavigation.cc @ 1627

Last change on this file since 1627 was 1627, checked in by rgrieder, 16 years ago

some adjustment to the default value setting in the overlay files

  • Property svn:eol-style set to native
File size: 10.1 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 "util/Convert.h"
39#include "core/ConsoleCommand.h"
40#include "core/CoreIncludes.h"
41#include "core/XMLPort.h"
42#include "objects/SpaceShip.h"
43#include "objects/Projectile.h"
44#include "objects/CameraHandler.h"
45#include "Radar.h"
46
47namespace orxonox
48{
49    CreateFactory(HUDNavigation);
50
51    HUDNavigation::HUDNavigation()
52        : navMarker_(0)
53        , aimMarker_(0)
54        , navText_(0)
55    {
56        RegisterObject(HUDNavigation);
57    }
58
59    HUDNavigation::~HUDNavigation()
60    {
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_);
67    }
68
69    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
70    {
71        OrxonoxOverlay::XMLPort(xmlElement, mode);
72
73        if (mode == XMLPort::LoadObject)
74        {
75            // create nav text
76            navText_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
77                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberStr()));
78
79            // create nav marker
80            navMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
81                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberStr()));
82            navMarker_->setMaterialName("Orxonox/NavArrows");
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           
90            background_->addChild(navMarker_);
91            background_->addChild(aimMarker_);
92            background_->addChild(navText_);
93
94            // hide at first
95            this->setVisible(false);
96
97            this->setFont("Monofur");
98            this->setTextSize(0.05f);
99            this->setNavMarkerSize(0.05f);
100            this->setAimMarkerSize(0.04f);
101        }
102
103        XMLPortParam(HUDNavigation, "font",     setFont,     getFont,     xmlElement, mode).defaultValues("Monofur");
104        XMLPortParam(HUDNavigation, "textSize", setTextSize, getTextSize, xmlElement, mode).defaultValues(0.05f);
105        XMLPortParam(HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode)
106            .defaultValues(0.05f);
107        XMLPortParam(HUDNavigation, "aimMarkerSize", setAimMarkerSize, getAimMarkerSize, xmlElement, mode)
108            .defaultValues(0.04f);
109    }
110
111    void HUDNavigation::setFont(const std::string& font)
112    {
113        if (this->navText_ && font != "")
114            this->navText_->setFontName(font);
115    }
116
117    const std::string& HUDNavigation::getFont() const
118    {
119        if (this->navText_)
120            return this->navText_->getFontName();
121        else
122            return blankString;
123    }
124
125    void HUDNavigation::setTextSize(float size)
126    {
127        if (this->navText_ && size >= 0.0f)
128            this->navText_->setCharHeight(size);
129    }
130
131    float HUDNavigation::getTextSize() const
132    {
133        if (this->navText_)
134            return this->navText_->getCharHeight();
135        else
136            return 0.0f;
137    }
138
139    void HUDNavigation::tick(float dt)
140    {
141        if (!Radar::getInstance().getFocus())
142        {
143            this->overlay_->hide();
144            return;
145        }
146        else
147        {
148            this->overlay_->show();
149        }
150
151        // set text
152        int dist = (int) getDist2Focus();
153        navText_->setCaption(convertToString(dist));
154        float textLength = convertToString(dist).size() * navText_->getCharHeight() * 0.3;
155
156        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
157        Matrix4 transformationMatrix = navCam->getProjectionMatrix() * navCam->getViewMatrix();
158        // transform to screen coordinates
159        Vector3 pos = transformationMatrix * Radar::getInstance().getFocus()->getWorldPosition();
160
161        bool outOfView;
162        if (pos.z > 1.0)
163        {
164            // z > 1.0 means that the object is behind the camera
165            outOfView = true;
166            // we have to switch all coordinates (if you don't know why,
167            // try linear algebra lectures, because I can't explain..)
168            pos.x = -pos.x;
169            pos.y = -pos.y;
170        }
171        else
172            outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
173
174        if (outOfView)
175        {
176            // object is not in view
177            aimMarker_->hide();
178
179            if (!wasOutOfView_)
180            {
181                navMarker_->setMaterialName("Orxonox/NavArrows");
182                wasOutOfView_ = true;
183            }
184
185            if (pos.x < pos.y)
186            {
187                if (pos.y > -pos.x)
188                {
189                    // up
190                    float position = pos.x / pos.y + 1.0;
191                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 0.0);
192                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
193                    navText_->setLeft((position - textLength) * 0.5);
194                    navText_->setTop(navMarker_->getHeight());
195                }
196                else
197                {
198                    // left
199                    float position = pos.y / pos.x + 1.0;
200                    navMarker_->setPosition(0.0, (position - navMarker_->getWidth()) * 0.5);
201                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
202                    navText_->setLeft(navMarker_->getWidth() + 0.01);
203                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
204                }
205            }
206            else
207            {
208                if (pos.y < -pos.x)
209                {
210                    // down
211                    float position = -pos.x / pos.y + 1.0;
212                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 1.0 - navMarker_->getHeight());
213                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
214                    navText_->setLeft((position - textLength) * 0.5);
215                    navText_->setTop(1.0 - navMarker_->getHeight() - navText_->getCharHeight());
216                }
217                else
218                {
219                    // right
220                    float position = -pos.y / pos.x + 1.0;
221                    navMarker_->setPosition(1.0 - navMarker_->getWidth(), (position - navMarker_->getHeight()) * 0.5);
222                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
223                    navText_->setLeft(1.0 - navMarker_->getWidth() - textLength - 0.01);
224                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
225                }
226            }
227        }
228        else
229        {
230            // object is in view
231
232            Vector3 aimpos = transformationMatrix * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(),
233                    Projectile::getSpeed(), Radar::getInstance().getFocus()->getWorldPosition(), Radar::getInstance().getFocus()->getOrientedVelocity());
234
235            if (wasOutOfView_)
236            {
237                navMarker_->setMaterialName("Orxonox/NavTDC");
238                wasOutOfView_ = false;
239            }
240
241            // object is in view
242            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
243            navMarker_->setLeft((pos.x + 1.0 - navMarker_->getWidth()) * 0.5);
244            navMarker_->setTop((-pos.y + 1.0 - navMarker_->getHeight()) * 0.5);
245
246            aimMarker_->show();
247            aimMarker_->setLeft((aimpos.x + 1.0 - aimMarker_->getWidth()) * 0.5);
248            aimMarker_->setTop((-aimpos.y + 1.0 - aimMarker_->getHeight()) * 0.5);
249
250            navText_->setLeft((pos.x + 1.0 + navMarker_->getWidth()) * 0.5);
251            navText_->setTop((-pos.y + 1.0 + navMarker_->getHeight()) * 0.5);
252        }
253    }
254
255    float HUDNavigation::getDist2Focus() const
256    {
257        if (Radar::getInstance().getFocus())
258            return (Radar::getInstance().getFocus()->getWorldPosition() - SpaceShip::getLocalShip()->getPosition()).length();
259        else
260            return 0;
261    }
262
263    /**
264    @brief Overridden method of OrxonoxOverlay. Usually the entire overlay
265           scales with scale(). Here we obviously have to adjust this.
266    */
267    void HUDNavigation::sizeChanged()
268    {
269        // use size to compensate for apspect ratio if enabled.
270        float xScale = this->getActualSize().x;
271        float yScale = this->getActualSize().y;
272        if (this->navMarker_)
273            navMarker_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
274        if (this->aimMarker_)
275            aimMarker_->setDimensions(aimMarkerSize_ * xScale, aimMarkerSize_ * yScale);
276        if (this->navText_)
277            navText_->setCharHeight(navText_->getCharHeight() * yScale);
278    }
279}
Note: See TracBrowser for help on using the repository browser.