Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/hud/Navigation.cc @ 1580

Last change on this file since 1580 was 1580, checked in by landauf, 16 years ago

started another attempt to fix the occasionally focus-cycling crash

  • Property svn:eol-style set to native
File size: 12.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:
25 *      ...
26 *
27 */
[1393]28
[1410]29#include "OrxonoxStableHeaders.h"
30#include "Navigation.h"
31
[1393]32#include <OgreOverlayManager.h>
[1395]33#include <OgreStringConverter.h>
[1410]34
35#include "GraphicsEngine.h"
36// TODO: remove the SpaceShip and CameraHandler dependencies
[1393]37#include "objects/SpaceShip.h"
[1566]38#include "objects/Projectile.h"
[1399]39#include "objects/CameraHandler.h"
[1410]40#include "RadarObject.h"
41#include "RadarOverlayElement.h"
[1393]42#include "HUD.h"
[1456]43#include "core/Debug.h"
[1564]44#include "util/Math.h"
[1393]45
46namespace orxonox
47{
48    using namespace Ogre;
49
[1580]50    Navigation::Navigation(OverlayContainer* container)
51    {
[1393]52        container_ = container;
53        focus_ = NULL;
54        init();
55    }
56
[1564]57    Navigation::~Navigation()
58    {
59        OverlayManager::getSingleton().destroyOverlayElement(this->navText_);
60        OverlayManager::getSingleton().destroyOverlayElement(this->navMarker_);
61        OverlayManager::getSingleton().destroyOverlayElement(this->aimMarker_);
62    }
63
[1580]64    void Navigation::init()
65    {
[1394]66        // create nav text
[1564]67        navText_ = static_cast<TextAreaOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("TextArea", "navText"));
[1394]68        navText_->show();
[1399]69        navText_->setMetricsMode(Ogre::GMM_PIXELS);
70        navText_->setDimensions(0.001, 0.001);
[1394]71        navText_->setPosition(0.02, 0.02);
72        navText_->setFontName("Console");
[1399]73        navText_->setCharHeight(20);
[1396]74        navText_->setCaption("");
[1564]75        navText_->hide();
[1394]76        container_->addChild(navText_);
77
78
[1393]79        // create nav marker ...
[1564]80        navMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", "NavMarker"));
81        aimMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", "aimMarker"));
[1393]82        navMarker_->setMetricsMode(GMM_PIXELS);
[1564]83        aimMarker_->setMetricsMode(GMM_PIXELS);
[1393]84        navMarker_->hide();
[1564]85        aimMarker_->hide();
[1566]86        aimMarker_->setMaterialName("Orxonox/NavCrosshair");
87        aimMarker_->setDimensions(20, 20);
88        aimMarker_->setUV(0.0, 0.0, 1.0, 1.0);
[1393]89        container_->addChild(navMarker_);
[1564]90        container_->addChild(aimMarker_);
[1410]91    }
[1393]92
[1580]93    void Navigation::update()
94    {
[1564]95        if (!focus_)
96            return;
[1400]97
[1399]98        updateMarker();
99    }
100
[1580]101    void Navigation::updateMarker()
102    {
[1564]103        int windowW = GraphicsEngine::getSingleton().getWindowWidth();
104        int windowH = GraphicsEngine::getSingleton().getWindowHeight();
105
[1399]106        // set text
[1457]107        int dist = (int) getDist2Focus()/100;
[1399]108        navText_->setCaption(Ogre::StringConverter::toString(dist));
109
[1564]110        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
[1399]111        // transform to screen coordinates
[1566]112        Vector3 pos = navCam->getProjectionMatrix() * navCam->getViewMatrix() * focus_->getPosition();
113        Vector3 aimpos = navCam->getProjectionMatrix() * navCam->getViewMatrix() * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(), Projectile::getSpeed(), focus_->getPosition(), focus_->getOrientedVelocity());
[1564]114
[1399]115        float xPosRel = 0.5*pos.x+0.5;
116        float yPosRel = 1-(0.5*pos.y+0.5);
[1566]117        float xAimPosRel = 0.5*aimpos.x+0.5;
118        float yAimPosRel = 1-(0.5*aimpos.y+0.5);
[1564]119        int xPos = (int) (xPosRel*windowW);
120        int yPos = (int) (yPosRel*windowH);
[1566]121        int xAimPos = (int) (xAimPosRel*windowW);
122        int yAimPos = (int) (yAimPosRel*windowH);
[1564]123        int xFromCenter = xPos-windowW/2;
124        int yFromCenter = yPos-windowH/2;
125
[1399]126        // is object in view?
[1564]127        Vector3 navCamPos = SpaceShip::getLocalShip()->getPosition();
128        Vector3 currentDir = SpaceShip::getLocalShip()->getDir();
129        Vector3 currentOrth = SpaceShip::getLocalShip()->getOrth();
130        float radius = getAngle(navCamPos, currentDir, focus_->getPosition());
131        bool isRight = (currentDir.crossProduct(currentOrth)).dotProduct(focus_->getPosition() - navCamPos)>0;
132        bool isAbove = currentOrth.dotProduct(focus_->getPosition() - navCamPos)>0;
[1399]133        bool outOfView = (xPosRel<0 || xPosRel>1 || yPosRel<0 || yPosRel>1);
[1580]134
[1399]135        // if object is behind us, it is out of view anyway:
[1580]136        if (!outOfView && radius > Ogre::Math::PI / 2)
137            outOfView = true;
[1399]138
[1580]139        if (outOfView)
140        {
[1411]141            // object is not in view
[1399]142            navMarker_->setMaterialName("Orxonox/NavArrows");
143            navMarker_->setDimensions(16,16);
[1566]144            aimMarker_->hide();
[1564]145            float phiUpperCorner = atan((float)(windowW)/(float)(windowH));
[1411]146            // from the angle we find out on which edge to draw the marker
[1399]147            // and which of the four arrows to take
[1411]148            float phiNav = atan((float) xFromCenter / (float) yFromCenter);
149
[1580]150            if (isAbove && isRight)
151            {
[1411]152                // top right quadrant
[1580]153                if (-phiNav < phiUpperCorner)
154                {
[1444]155                    //COUT(3) << "arrow up\n";
[1564]156                    navMarker_->setPosition(-tan(phiNav)*windowH/2+windowW/2, 0);
[1399]157                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
158                    navText_->setLeft(navMarker_->getLeft()+navMarker_->getWidth());
159                    navText_->setTop(navMarker_->getHeight());
160                }
[1580]161                else
162                {
[1444]163                    //COUT(3) << "arrow right\n";
[1564]164                    navMarker_->setPosition(windowW-16, tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
[1411]165                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
166                    navText_->setLeft(navMarker_->getLeft()-navMarker_->getWidth());
167                    navText_->setTop(navMarker_->getTop()+navMarker_->getHeight());
168                }
169            }
[1580]170            if (!isAbove && isRight)
171            {
[1411]172                // bottom right quadrant
[1580]173                if (phiNav < phiUpperCorner)
174                {
[1444]175                    //COUT(3) << "arrow down\n";
[1564]176                    navMarker_->setPosition(tan(phiNav)*windowH/2+windowW/2, windowH-16);
[1399]177                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
178                    navText_->setLeft(navMarker_->getLeft()+navMarker_->getWidth());
179                    navText_->setTop(navMarker_->getTop()-navMarker_->getHeight());
180                }
[1580]181                else
182                {
[1444]183                    //COUT(3) << "arrow right\n";
[1564]184                    navMarker_->setPosition(windowW-16, tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
[1399]185                    navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
186                    navText_->setLeft(navMarker_->getLeft()-navMarker_->getWidth());
187                    navText_->setTop(navMarker_->getTop()+navMarker_->getHeight());
188                }
[1393]189            }
[1580]190            if (isAbove && !isRight)
191            {
[1411]192                // top left quadrant
[1580]193                if (phiNav<phiUpperCorner)
194                {
[1444]195                    //COUT(3) << "arrow up\n";
[1564]196                    navMarker_->setPosition(-tan(phiNav)*windowH/2+windowW/2, 0);
[1399]197                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
198                    navText_->setLeft(navMarker_->getLeft()+navMarker_->getWidth());
199                    navText_->setTop(navMarker_->getHeight());
200                }
[1580]201                else
202                {
[1444]203                    //COUT(3) << "arrow left\n";
[1564]204                    navMarker_->setPosition(0, -tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
[1411]205                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
206                    navText_->setLeft(navMarker_->getWidth());
207                    navText_->setTop(navMarker_->getTop()+navMarker_->getHeight());
208                }
209            }
[1580]210            if (!isAbove && !isRight)
211            {
[1411]212                // bottom left quadrant
[1580]213                if (phiNav>-phiUpperCorner)
214                {
[1444]215                    //COUT(3) << "arrow down\n";
[1564]216                    navMarker_->setPosition(tan(phiNav)*windowH/2+windowW/2, windowH-16);
[1399]217                    navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
218                    navText_->setLeft(navMarker_->getLeft()+navMarker_->getWidth());
219                    navText_->setTop(navMarker_->getTop()-navMarker_->getHeight());
220                }
[1580]221                else
222                {
[1444]223                    //COUT(3) << "arrow left\n";
[1564]224                    navMarker_->setPosition(0, -tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
[1399]225                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
226                    navText_->setLeft(navMarker_->getWidth());
227                    navText_->setTop(navMarker_->getTop()+navMarker_->getHeight());
228                }
[1393]229            }
230        }
[1580]231        else
232        {
[1411]233            // object is in view
[1399]234            navMarker_->setMaterialName("Orxonox/NavTDC");
[1566]235            navMarker_->setDimensions(35, 35);
[1459]236            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
[1399]237            navMarker_->setPosition(xPos-navMarker_->getWidth()/2, yPos-navMarker_->getHeight()/2);
[1566]238
239            aimMarker_->show();
240            aimMarker_->setPosition(xAimPos-aimMarker_->getWidth()/2, yAimPos-aimMarker_->getHeight()/2);
241
[1399]242            navText_->setPosition(xPos+navMarker_->getWidth()/2, yPos+navMarker_->getHeight()/2);
[1393]243        }
[1410]244    }
[1394]245
[1580]246    void Navigation::cycleFocus()
247    {
248        if (!focus_)
249        {
[1564]250            // Get closest object
251            float distance = (unsigned int) -1;
252            Vector3 shipPos = SpaceShip::getLocalShip()->getPosition();
253            it_ = HUD::getSingleton().getRadarObjects().begin();
254
255            for (std::list<RadarObject*>::iterator it = HUD::getSingleton().getRadarObjects().begin(); it != HUD::getSingleton().getRadarObjects().end(); ++it)
256            {
257                float newdist = (*it)->getPosition().squaredDistance(shipPos);
258                if (newdist < distance)
259                {
260                    distance = newdist;
261                    it_ = it;
262                }
263            }
264
265            if (it_ != HUD::getSingleton().getRadarObjects().end())
266            {
267                focus_ = *it_;
268
269                // move the focused object to the begin of the list, so we will iterate through all other objects when cycling
270                HUD::getSingleton().getRadarObjects().erase(it_);
271                HUD::getSingleton().getRadarObjects().insert(HUD::getSingleton().getRadarObjects().begin(), focus_);
272                it_ = HUD::getSingleton().getRadarObjects().begin();
273            }
[1410]274        }
[1580]275        else if (it_ != HUD::getSingleton().getRadarObjects().end())
276        {
[1562]277            focus_->resetMaterial();
[1580]278            ++it_;
279            if (it_ != HUD::getSingleton().getRadarObjects().end())
[1456]280                focus_ = *it_;
[1580]281            else
282                focus_ = 0;
[1393]283        }
[1580]284        else
285        {
286            focus_ = 0;
287        }
[1564]288        updateFocus();
289    }
290
[1580]291    void Navigation::updateFocus()
292    {
293        if (focus_)
294        {
295            navMarker_->show();
296            navText_->show();
297            focus_->setColour(ColourValue::White);
298        }
299        else
300        {
[1393]301            navMarker_->hide();
[1566]302            aimMarker_->hide();
[1399]303            navText_->hide();
[1393]304        }
[1410]305    }
[1393]306
[1568]307    void Navigation::releaseFocus()
308    {
309        this->focus_ = 0;
310        this->updateFocus();
311    }
312
[1580]313    float Navigation::getDist2Focus() const
314    {
315        if (focus_)
316            return (focus_->getPosition() - SpaceShip::getLocalShip()->getPosition()).length();
317        else
318            return 0;
[1410]319    }
[1393]320}
Note: See TracBrowser for help on using the repository browser.