Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1601 was 1601, checked in by rgrieder, 16 years ago
  • new folder structure for overlays:

orxonox/


overlays/

console/
hud/

  • Navigation —> HUDNavigation
  • HUD —> OverlayGroup (not yet begun with that except renaming and getHUD() instead of getSingleton())
  • moved HUD.oxo (file ending should stand for orxonox overlay) to media repository in overlay folder
  • fixed a bug with console noiseSize_ config value (was inverted..)
  • Property svn:eol-style set to native
File size: 12.7 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 <OgreStringConverter.h>
34
35//#include "GraphicsEngine.h"
36// TODO: remove the SpaceShip and CameraHandler dependencies
37#include "objects/SpaceShip.h"
38#include "objects/Projectile.h"
39#include "objects/CameraHandler.h"
40#include "overlays/OverlayGroup.h"
41#include "RadarObject.h"
42#include "RadarOverlayElement.h"
43#include "core/Debug.h"
44#include "core/CoreIncludes.h"
45
46namespace orxonox
47{
48    CreateFactory(HUDNavigation);
49
50    using namespace Ogre;
51
52    HUDNavigation::HUDNavigation()
53      : container_(0)
54      , navMarker_(0)
55      , aimMarker_(0)
56      , navText_(0)
57      , focus_(0)
58    {
59        RegisterObject(HUDNavigation);
60    }
61
62    HUDNavigation::~HUDNavigation()
63    {
64        if (this->isInitialized())
65        {
66            if (this->container_)
67                OverlayManager::getSingleton().destroyOverlayElement(this->container_);
68            if (this->navMarker_)
69                OverlayManager::getSingleton().destroyOverlayElement(this->navMarker_);
70            if (this->navText_)
71                OverlayManager::getSingleton().destroyOverlayElement(this->navText_);
72            if (this->aimMarker_)
73                OverlayManager::getSingleton().destroyOverlayElement(this->aimMarker_);
74        }
75    }
76
77    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
78    {
79        OrxonoxOverlay::XMLPort(xmlElement, mode);
80
81        if (mode == XMLPort::LoadObject)
82        {
83            // create container
84            container_ = static_cast<OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", getName() + "_navContainer"));
85            container_->setMetricsMode(Ogre::GMM_RELATIVE);
86            container_->setLeft(0.0);
87            container_->setTop(0.0);
88            container_->setWidth(1.0);
89            container_->setHeight(1.0);
90
91            // create nav text
92            navText_ = static_cast<TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", getName() + "_navText"));
93            navText_->setMetricsMode(Ogre::GMM_RELATIVE);
94            navText_->setPosition(0.0f, 0.0f);
95            navText_->setCharHeight(0.05f);
96            navText_->setFontName("Monofur");
97
98            // create nav marker
99            navMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", getName() + "_navMarker"));
100            navMarker_->setMetricsMode(GMM_RELATIVE);
101            navMarker_->setMaterialName("Orxonox/NavArrows");
102            this->navMarkerSize_ = 0.05;
103            this->wasOutOfView_ = true; // just a to ensure the material is changed right the first time..
104
105            // create aim marker
106            aimMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", getName() + "_aimMarker"));
107            aimMarker_->setMetricsMode(GMM_RELATIVE);
108            aimMarker_->setMaterialName("Orxonox/NavCrosshair");
109            this->aimMarkerSize_ = 0.04;
110           
111            container_->addChild(navMarker_);
112            container_->addChild(aimMarker_);
113            container_->addChild(navText_);
114            container_->show();
115
116            this->overlay_->add2D(container_);
117            this->overlay_->hide();
118        }
119
120        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlElement, mode);
121        XMLPortParam(HUDNavigation, "textsize", setTextSize, getTextSize, xmlElement, mode);
122        XMLPortParam(HUDNavigation, "navmarkersize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
123        XMLPortParam(HUDNavigation, "aimmarkersize", setAimMarkerSize, getAimMarkerSize, xmlElement, mode);
124
125        if (mode == XMLPort::LoadObject)
126        {
127            this->sizeChanged();
128        }
129    }
130
131    void HUDNavigation::setNavMarkerSize(float size)
132    {
133        this->navMarkerSize_ = size;
134    }
135
136    float HUDNavigation::getNavMarkerSize() const
137    {
138        return this->navMarkerSize_;
139    }
140
141    void HUDNavigation::setAimMarkerSize(float size)
142    {
143        this->aimMarkerSize_ = size;
144    }
145
146    float HUDNavigation::getAimMarkerSize() const
147    {
148        return this->aimMarkerSize_;
149    }
150
151    void HUDNavigation::setFont(const std::string& font)
152    {
153        if (this->navText_ && font != "")
154            this->navText_->setFontName(font);
155    }
156
157    std::string HUDNavigation::getFont() const
158    {
159        if (this->navText_)
160            return this->navText_->getFontName();
161        else
162            return "";
163    }
164
165    void HUDNavigation::setTextSize(float size)
166    {
167        if (this->navText_ && size >= 0.0f)
168            this->navText_->setCharHeight(size);
169    }
170
171    float HUDNavigation::getTextSize() const
172    {
173        if (this->navText_)
174            return this->navText_->getCharHeight();
175        else
176            return 0.0f;
177    }
178
179    void HUDNavigation::tick(float dt)
180    {
181        if (!focus_)
182            return;
183
184        updateMarker();
185    }
186
187    void HUDNavigation::updateMarker()
188    {
189        // set text
190        int dist = (int) getDist2Focus()/100.0f;
191        navText_->setCaption(convertToString(dist));
192        float textLength = convertToString(dist).size() * navText_->getCharHeight() * 0.3;
193
194        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
195        Matrix4 transformationMatrix = navCam->getProjectionMatrix() * navCam->getViewMatrix();
196        // transform to screen coordinates
197        Vector3 pos = transformationMatrix * focus_->getPosition();
198
199        bool outOfView;
200        if (pos.z > 1.0)
201        {
202            // z > 1.0 means that the object is behind the camera
203            outOfView = true;
204            // we have to switch all coordinates (if you don't know why,
205            // try linear algebra lectures, because I can't explain..)
206            pos.x = -pos.x;
207            pos.y = -pos.y;
208        }
209        else
210            outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
211
212        if (outOfView)
213        {
214            // object is not in view
215            aimMarker_->hide();
216
217            if (!wasOutOfView_)
218            {
219                navMarker_->setMaterialName("Orxonox/NavArrows");
220                wasOutOfView_ = true;
221            }
222
223            if (pos.x < pos.y)
224            {
225                if (pos.y > -pos.x)
226                {
227                    // up
228                    float position = pos.x / pos.y + 1.0;
229                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 0.0);
230                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
231                    navText_->setLeft((position - textLength) * 0.5);
232                    navText_->setTop(navMarker_->getHeight());
233                }
234                else
235                {
236                    // left
237                    float position = pos.y / pos.x + 1.0;
238                    navMarker_->setPosition(0.0, (position - navMarker_->getWidth()) * 0.5);
239                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
240                    navText_->setLeft(navMarker_->getWidth() + 0.01);
241                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
242                }
243            }
244            else
245            {
246                if (pos.y < -pos.x)
247                {
248                    // down
249                    float position = -pos.x / pos.y + 1.0;
250                    navMarker_->setPosition((position - navMarker_->getWidth()) * 0.5, 1.0 - navMarker_->getHeight());
251                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
252                    navText_->setLeft((position - textLength) * 0.5);
253                    navText_->setTop(1.0 - navMarker_->getHeight() - navText_->getCharHeight());
254                }
255                else
256                {
257                    // right
258                    float position = -pos.y / pos.x + 1.0;
259                    navMarker_->setPosition(1.0 - navMarker_->getWidth(), (position - navMarker_->getHeight()) * 0.5);
260                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
261                    navText_->setLeft(1.0 - navMarker_->getWidth() - textLength - 0.01);
262                    navText_->setTop((position - navText_->getCharHeight()) * 0.5);
263                }
264            }
265        }
266        else
267        {
268            // object is in view
269
270            Vector3 aimpos = transformationMatrix * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(),
271                    Projectile::getSpeed(), focus_->getPosition(), focus_->getOrientedVelocity());
272
273            if (wasOutOfView_)
274            {
275                navMarker_->setMaterialName("Orxonox/NavTDC");
276                wasOutOfView_ = false;
277            }
278
279            // object is in view
280            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
281            navMarker_->setLeft((pos.x + 1.0 - navMarker_->getWidth()) * 0.5);
282            navMarker_->setTop((-pos.y + 1.0 - navMarker_->getHeight()) * 0.5);
283
284            aimMarker_->show();
285            aimMarker_->setLeft((aimpos.x + 1.0 - aimMarker_->getWidth()) * 0.5);
286            aimMarker_->setTop((-aimpos.y + 1.0 - aimMarker_->getHeight()) * 0.5);
287
288            navText_->setLeft((pos.x + 1.0 + navMarker_->getWidth()) * 0.5);
289            navText_->setTop((-pos.y + 1.0 + navMarker_->getHeight()) * 0.5);
290        }
291    }
292
293    void HUDNavigation::cycleFocus()
294    {
295        if (!focus_)
296        {
297            // Get closest object
298            float distance = (unsigned int) -1;
299            Vector3 shipPos = SpaceShip::getLocalShip()->getPosition();
300            it_ = OverlayGroup::getHUD().getRadarObjects().begin();
301
302            for (std::list<RadarObject*>::iterator it = OverlayGroup::getHUD().getRadarObjects().begin(); it != OverlayGroup::getHUD().getRadarObjects().end(); ++it)
303            {
304                float newdist = (*it)->getPosition().squaredDistance(shipPos);
305                if (newdist < distance)
306                {
307                    distance = newdist;
308                    it_ = it;
309                }
310            }
311
312            if (it_ != OverlayGroup::getHUD().getRadarObjects().end())
313            {
314                focus_ = *it_;
315
316                // move the focused object to the begin of the list, so we will iterate through all other objects when cycling
317                OverlayGroup::getHUD().getRadarObjects().erase(it_);
318                OverlayGroup::getHUD().getRadarObjects().insert(OverlayGroup::getHUD().getRadarObjects().begin(), focus_);
319                it_ = OverlayGroup::getHUD().getRadarObjects().begin();
320            }
321        }
322        else if (it_ != OverlayGroup::getHUD().getRadarObjects().end())
323        {
324            focus_->resetMaterial();
325            ++it_;
326            if (it_ != OverlayGroup::getHUD().getRadarObjects().end())
327                focus_ = *it_;
328            else
329                focus_ = 0;
330        }
331        else
332        {
333            focus_ = 0;
334        }
335        updateFocus();
336    }
337
338    void HUDNavigation::updateFocus()
339    {
340        if (focus_)
341        {
342            overlay_->show();
343            focus_->setColour(ColourValue::White);
344        }
345        else
346        {
347            overlay_->hide();
348        }
349    }
350
351    void HUDNavigation::releaseFocus()
352    {
353        this->focus_ = 0;
354        this->updateFocus();
355    }
356
357    float HUDNavigation::getDist2Focus() const
358    {
359        if (focus_)
360            return (focus_->getPosition() - SpaceShip::getLocalShip()->getPosition()).length();
361        else
362            return 0;
363    }
364
365    void HUDNavigation::sizeChanged()
366    {
367        float xScale = this->getActualSize().x;
368        float yScale = this->getActualSize().y;
369        if (this->navMarker_)
370            navMarker_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
371        if (this->aimMarker_)
372            aimMarker_->setDimensions(aimMarkerSize_ * xScale, aimMarkerSize_ * yScale);
373        if (this->navText_)
374            navText_->setCharHeight(navText_->getCharHeight() * yScale);
375    }
376}
Note: See TracBrowser for help on using the repository browser.