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
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 *      ...
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/CameraHandler.h"
39#include "RadarObject.h"
40#include "RadarOverlayElement.h"
41#include "HUD.h"
42#include "core/Debug.h"
43#include "util/Math.h"
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
61    Navigation::~Navigation()
62    {
63        OverlayManager::getSingleton().destroyOverlayElement(this->navText_);
64        OverlayManager::getSingleton().destroyOverlayElement(this->navMarker_);
65        OverlayManager::getSingleton().destroyOverlayElement(this->aimMarker_);
66    }
67
68    void Navigation::init(){
69        // create nav text
70        navText_ = static_cast<TextAreaOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("TextArea", "navText"));
71        navText_->show();
72        navText_->setMetricsMode(Ogre::GMM_PIXELS);
73        navText_->setDimensions(0.001, 0.001);
74        navText_->setPosition(0.02, 0.02);
75        navText_->setFontName("Console");
76        navText_->setCharHeight(20);
77        navText_->setCaption("");
78        navText_->hide();
79        container_->addChild(navText_);
80
81
82        // create nav marker ...
83        navMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", "NavMarker"));
84        aimMarker_ = static_cast<PanelOverlayElement*>(OverlayManager::getSingleton().createOverlayElement("Panel", "aimMarker"));
85        navMarker_->setMetricsMode(GMM_PIXELS);
86        aimMarker_->setMetricsMode(GMM_PIXELS);
87        navMarker_->hide();
88        aimMarker_->hide();
89        container_->addChild(navMarker_);
90        container_->addChild(aimMarker_);
91    }
92
93    void Navigation::update(){
94        if (!focus_)
95            return;
96
97        updateMarker();
98    }
99
100    void Navigation::updateMarker(){
101        int windowW = GraphicsEngine::getSingleton().getWindowWidth();
102        int windowH = GraphicsEngine::getSingleton().getWindowHeight();
103
104        // set text
105        int dist = (int) getDist2Focus()/100;
106        navText_->setCaption(Ogre::StringConverter::toString(dist));
107
108        Vector3 pos = focus_->getPosition();
109        Ogre::Camera* navCam = SpaceShip::getLocalShip()->getCamera()->cam_;
110        // transform to screen coordinates
111        pos = navCam->getProjectionMatrix() * navCam->getViewMatrix() * pos;
112
113        float xPosRel = 0.5*pos.x+0.5;
114        float yPosRel = 1-(0.5*pos.y+0.5);
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
120        // is object in view?
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;
127        bool outOfView = (xPosRel<0 || xPosRel>1 || yPosRel<0 || yPosRel>1);
128        // if object is behind us, it is out of view anyway:
129        if(!outOfView && radius > Ogre::Math::PI / 2) outOfView = true;
130
131        if(outOfView){
132            // object is not in view
133            navMarker_->setMaterialName("Orxonox/NavArrows");
134            navMarker_->setDimensions(16,16);
135            float phiUpperCorner = atan((float)(windowW)/(float)(windowH));
136            // from the angle we find out on which edge to draw the marker
137            // and which of the four arrows to take
138            float phiNav = atan((float) xFromCenter / (float) yFromCenter);
139
140            if(isAbove && isRight){
141                // top right quadrant
142                if(-phiNav<phiUpperCorner){
143                    //COUT(3) << "arrow up\n";
144                    navMarker_->setPosition(-tan(phiNav)*windowH/2+windowW/2, 0);
145                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
146                    navText_->setLeft(navMarker_->getLeft()+navMarker_->getWidth());
147                    navText_->setTop(navMarker_->getHeight());
148                }
149                else {
150                    //COUT(3) << "arrow right\n";
151                    navMarker_->setPosition(windowW-16, tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
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) {
160                    //COUT(3) << "arrow down\n";
161                    navMarker_->setPosition(tan(phiNav)*windowH/2+windowW/2, windowH-16);
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 {
167                    //COUT(3) << "arrow right\n";
168                    navMarker_->setPosition(windowW-16, tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
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                }
173            }
174            if(isAbove && !isRight){
175                // top left quadrant
176                if(phiNav<phiUpperCorner){
177                    //COUT(3) << "arrow up\n";
178                    navMarker_->setPosition(-tan(phiNav)*windowH/2+windowW/2, 0);
179                    navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
180                    navText_->setLeft(navMarker_->getLeft()+navMarker_->getWidth());
181                    navText_->setTop(navMarker_->getHeight());
182                }
183                else {
184                    //COUT(3) << "arrow left\n";
185                    navMarker_->setPosition(0, -tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
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) {
194                    //COUT(3) << "arrow down\n";
195                    navMarker_->setPosition(tan(phiNav)*windowH/2+windowW/2, windowH-16);
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 {
201                    //COUT(3) << "arrow left\n";
202                    navMarker_->setPosition(0, -tan((3.14-2*phiNav)/2)*windowW/2+windowH/2);
203                    navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
204                    navText_->setLeft(navMarker_->getWidth());
205                    navText_->setTop(navMarker_->getTop()+navMarker_->getHeight());
206                }
207            }
208        }
209        else{
210            // object is in view
211            navMarker_->setMaterialName("Orxonox/NavTDC");
212            navMarker_->setDimensions(24,24);
213            navMarker_->setUV(0.0, 0.0, 1.0, 1.0);
214            navMarker_->setPosition(xPos-navMarker_->getWidth()/2, yPos-navMarker_->getHeight()/2);
215            navText_->setPosition(xPos+navMarker_->getWidth()/2, yPos+navMarker_->getHeight()/2);
216        }
217    }
218
219    void Navigation::cycleFocus(){
220        if(focus_ == NULL){
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            }
246        }
247        else{
248            focus_->resetMaterial();
249            if(it_ != HUD::getSingleton().getRadarObjects().end()){
250                focus_ = *it_;
251                ++it_;
252            }
253            else focus_ = NULL;
254        }
255        updateFocus();
256    }
257
258    void Navigation::updateFocus(){
259        if(focus_ == NULL){
260            navMarker_->hide();
261            navText_->hide();
262        }
263        else{
264            navMarker_->show();
265            navText_->show();
266            focus_->setColour(ColourValue::White);
267        }
268    }
269
270    float Navigation::getDist2Focus() const {
271        if(focus_ == NULL) return(0.0);
272        return((focus_->getPosition()-SpaceShip::getLocalShip()->getPosition()).length());
273    }
274}
Note: See TracBrowser for help on using the repository browser.