Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1564 was 1564, checked in by landauf, 16 years ago
  • several small changes in most of the HUD classes (code cleanup): removed obsolete variables, privatized all member variables, removed resizing functioncalls from tick, destroying overlayelements, added some const qualifiers.
  • moved calculation functions for RadarObject-position to Math.h and changed the phi/right/radius format to Vector2. the functions are used too by SpaceShipAI.
  • cycleNavigationFocus takes the nearest object if focus was NULL
  • BarOverlayElement works in both directions (left to right and right to left)
  • fixed bug causing SpaceShipAI to not stop shooting when losing target - this also speeds up orxonox a lot, because there are less projectiles

####################################

!! UPDATE YOUR MEDIA REPOSITORY !!

####################################
…or the BarOverlayElement will look strange

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