Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/hud/src/orxonox/hud/Navigation.cc @ 1590

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

svn save, just in case our house burns down over night…

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