Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/overlays/hud/HUDNavigation.cc @ 10427

Last change on this file since 10427 was 10294, checked in by landauf, 10 years ago

made projectiles slower (and all have the same speed now). makes it possible to dodge a projectile

  • Property svn:eol-style set to native
File size: 31.8 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 *      Oliver Scheuss
27 *      Matthias Spalinger
28 *
29 */
30
31#include "HUDNavigation.h"
32
33#include <OgreCamera.h>
34#include <OgreFontManager.h>
35#include <OgreOverlayManager.h>
36#include <OgreTextAreaOverlayElement.h>
37#include <OgrePanelOverlayElement.h>
38
39#include <typeinfo>
40
41#include "util/Math.h"
42#include "util/Convert.h"
43#include "core/command/ConsoleCommand.h"
44#include "core/CoreIncludes.h"
45#include "core/XMLPort.h"
46#include "CameraManager.h"
47#include "Scene.h"
48#include "Radar.h"
49#include "graphics/Camera.h"
50#include "controllers/HumanController.h"
51#include "worldentities/pawns/Pawn.h"
52#include "worldentities/WorldEntity.h"
53#include "core/config/ConfigValueIncludes.h"
54#include "tools/TextureGenerator.h"
55// #include <boost/bind/bind_template.hpp>
56
57
58namespace orxonox
59{
60
61    SetConsoleCommand("HUDNavigation","selectClosest", &HUDNavigation::selectClosestTarget).addShortcut().keybindMode(KeybindMode::OnPress);
62    SetConsoleCommand("HUDNavigation","selectNext", &HUDNavigation::selectNextTarget).addShortcut().keybindMode(KeybindMode::OnPress);
63
64    static bool compareDistance(std::pair<RadarViewable*, unsigned int> a,
65            std::pair<RadarViewable*, unsigned int> b)
66    {
67        return a.second < b.second;
68    }
69    RegisterClass ( HUDNavigation );
70
71    HUDNavigation* HUDNavigation::localHUD_s = 0;
72
73    HUDNavigation::HUDNavigation(Context* context) :
74        OrxonoxOverlay(context)
75    {
76        RegisterObject(HUDNavigation);
77        this->setConfigValues();
78
79        // Set default values
80        this->setFont("Monofur");
81        this->setTextSize(0.05f);
82        this->setNavMarkerSize(0.03f);
83        this->setAimMarkerSize(0.02f);
84        this->setHealthMarkerSize(0.06f);
85        this->setHealthLevelMarkerSize(0.06f);
86
87        this->setDetectionLimit(10000.0f);
88        this->currentMunitionSpeed_ = 750.0f;
89
90        this->closestTarget_ = true;
91        this->nextTarget_ = false;
92        HUDNavigation::localHUD_s = this;
93    }
94
95    HUDNavigation::~HUDNavigation()
96    {
97        if (this->isInitialized())
98        {
99            for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it != this->activeObjectList_.end();)
100            removeObject((it++)->first);
101        }
102        this->sortedObjectList_.clear();
103    }
104
105    void HUDNavigation::setConfigValues()
106    {
107        SetConfigValue(markerLimit_, 3);
108        SetConfigValue(showDistance_, false);
109    }
110
111    void HUDNavigation::XMLPort(Element& xmlelement, XMLPort::Mode mode)
112    {
113        SUPER(HUDNavigation, XMLPort, xmlelement, mode);
114
115        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlelement, mode);
116        XMLPortParam(HUDNavigation, "textSize", setTextSize, getTextSize, xmlelement, mode);
117        XMLPortParam(HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlelement, mode);
118        XMLPortParam(HUDNavigation, "detectionLimit", setDetectionLimit, getDetectionLimit, xmlelement, mode);
119        XMLPortParam(HUDNavigation, "aimMarkerSize", setAimMarkerSize, getAimMarkerSize, xmlelement, mode);
120        XMLPortParam(HUDNavigation, "healthMarkerSize", setHealthMarkerSize, getHealthMarkerSize, xmlelement, mode);
121        XMLPortParam(HUDNavigation, "healthLevelMarkerSize", setHealthLevelMarkerSize, getHealthLevelMarkerSize, xmlelement, mode);
122
123    }
124
125    void HUDNavigation::setFont(const std::string& font)
126    {
127        const Ogre::ResourcePtr& fontPtr = Ogre::FontManager::getSingleton().getByName(font);
128        if (fontPtr.isNull())
129        {
130            orxout(internal_warning) << "HUDNavigation: Font '" << font << "' not found" << endl;
131            return;
132        }
133        this->fontName_ = font;
134        for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it != this->activeObjectList_.end(); ++it)
135        {
136            if (it->second.text_ != NULL)
137                it->second.text_->setFontName(this->fontName_);
138        }
139    }
140
141    const std::string& HUDNavigation::getFont() const
142    {
143        return this->fontName_;
144    }
145
146    void HUDNavigation::setTextSize(float size)
147    {
148        if (size <= 0.0f)
149        {
150            orxout(internal_warning) << "HUDNavigation: Negative font size not allowed" << endl;
151            return;
152        }
153        this->textSize_ = size;
154        for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it!=this->activeObjectList_.end(); ++it)
155        {
156            if (it->second.text_)
157                it->second.text_->setCharHeight(size);
158        }
159    }
160
161    float HUDNavigation::getTextSize() const
162    {
163        return this->textSize_;
164    }
165
166    float HUDNavigation::getArrowSizeX(int dist) const
167    {
168        if (dist < 600)
169        dist = 600;
170        return this->getActualSize().x * 900 * this->navMarkerSize_ / dist;
171    }
172
173    float HUDNavigation::getArrowSizeY(int dist) const
174    {
175        if (dist < 600)
176        dist = 600;
177        return this->getActualSize().y * 900 * this->navMarkerSize_ / dist;
178    }
179
180    void HUDNavigation::tick(float dt)
181    {
182        SUPER(HUDNavigation, tick, dt);
183
184        Camera* cam = CameraManager::getInstance().getActiveCamera();
185        if (cam == NULL)
186        return;
187        const Matrix4& camTransform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
188
189        for (std::list<std::pair<RadarViewable*, unsigned int> >::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++listIt)
190        listIt->second = (int)((listIt->first->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f);
191
192        this->sortedObjectList_.sort(compareDistance);
193
194        unsigned int markerCount = 0;
195        bool closeEnough = false; // only display objects that are close enough to be relevant for the player
196
197        // if the selected object doesn't exist any more or is now out of range select the closest object
198        std::map<RadarViewable*, ObjectInfo>::iterator selectedActiveObject = this->activeObjectList_.find(this->selectedTarget_);
199        if(selectedActiveObject == this->activeObjectList_.end())
200        {
201            this->closestTarget_ = true;
202        }
203        else if(this->detectionLimit_ < (this->selectedTarget_->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f)
204        {
205            this->closestTarget_ = true;
206            selectedActiveObject->second.selected_ = false;
207        }
208
209        bool nextHasToBeSelected = false;
210
211        for (std::list<std::pair<RadarViewable*, unsigned int> >::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++markerCount, ++listIt)
212        {
213
214            std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.find(listIt->first);
215            closeEnough = listIt->second < this->detectionLimit_;
216            // display radarviewables on HUD if the marker limit and max-distance is not exceeded
217            if (markerCount < this->markerLimit_ && (closeEnough || this->detectionLimit_ < 0))
218            {
219                // Get Distance to HumanController and save it in the TextAreaOverlayElement.
220                int dist = listIt->second;
221                float textLength = 0.0f;
222
223                if (this->showDistance_)
224                {
225                    //display distance next to cursor
226                    it->second.text_->setCaption(multi_cast<std::string>(dist));
227                    textLength = multi_cast<std::string>(dist).size() * it->second.text_->getCharHeight() * 0.3f;
228                }
229                else
230                {
231                    //display name next to cursor
232                    it->second.text_->setCaption(it->first->getRadarName());
233                    textLength = it->first->getRadarName().size() * it->second.text_->getCharHeight() * 0.3f;
234                }
235
236                // select the object that aim-assistant indicates
237                if(this->closestTarget_)
238                // select the closest object
239                {
240                    if(listIt == this->sortedObjectList_.begin())
241                    {
242                        it->second.selected_ = true;
243                        this->selectedTarget_ = it->first;
244                    }
245                    else if(it->second.selected_)
246                    {
247                        it->second.selected_ = false;
248                    }
249
250                }
251                else if(this->nextTarget_)
252                // select the next object in sortedObjectList
253                {
254                    if(nextHasToBeSelected){
255                        it->second.selected_ = true;
256                        this->selectedTarget_ = it->first;
257                        nextHasToBeSelected = false;
258                    }
259                    else if(it->second.selected_)
260                    {
261                        nextHasToBeSelected = true;
262                        it->second.selected_ = false;
263
264                        // check if there's a next object
265                        listIt++;
266                        if(listIt != this->sortedObjectList_.end())
267                        {
268                            // and if the marker limit and max-distance are not exceeded for it
269                            if (markerCount + 1 >= this->markerLimit_ ||
270                                    (listIt->second > this->detectionLimit_ && detectionLimit_ >= 0))
271                            {
272                                // otherwise select the closest object
273                                this->activeObjectList_.find(this->sortedObjectList_.begin()->first)->second.selected_ = true;
274                                this->selectedTarget_ = it->first;
275                                nextHasToBeSelected = false;
276                            }
277                        }
278                        listIt--;
279                    }
280                }
281
282
283
284
285                // Transform to screen coordinates
286                Vector3 pos = camTransform * it->first->getRVWorldPosition();
287
288                bool outOfView = true;
289                if (pos.z > 1.0)
290                {
291                    // z > 1.0 means that the object is behind the camera
292                    outOfView = true;
293                    // we have to switch all coordinates (if you don't know why,
294                    // try linear algebra lectures, because I can't explain..)
295                    pos.x = -pos.x;
296                    pos.y = -pos.y;
297                }
298                else
299                    outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
300
301                if (outOfView)
302                {
303                    // Object is not in view
304
305                    // Change material only if outOfView changed
306                    if (!it->second.wasOutOfView_)
307                    {
308                        it->second.health_->hide();
309                        it->second.healthLevel_->hide();
310                        it->second.panel_->setMaterialName(TextureGenerator::getMaterialName("arrows.png", it->first->getRadarObjectColour()));
311                        it->second.wasOutOfView_ = true;
312                        it->second.target_->hide();
313                    }
314
315                    //float xDistScale = this->getActualSize().x * 1000.0f * this->navMarkerSize_ / dist;
316                    //float yDistScale = this->getActualSize().y * 1000.0f * this->navMarkerSize_ / dist;
317
318                    // Adjust Arrowsize according to distance
319                    it->second.panel_->setDimensions(getArrowSizeX(dist), getArrowSizeY(dist));
320
321                    // Switch between top, bottom, left and right position of the arrow at the screen border
322                    if (pos.x < pos.y)
323                    {
324                        if (pos.y > -pos.x)
325                        {
326                            // Top
327                            float position = pos.x / pos.y + 1.0f;
328                            it->second.panel_->setPosition((position - it->second.panel_->getWidth()) * 0.5f, 0.0f);
329                            it->second.panel_->setUV(0.5f, 0.0f, 1.0f, 0.5f);
330                            it->second.text_->setLeft((position - textLength) * 0.5f);
331                            it->second.text_->setTop(it->second.panel_->getHeight());
332                        }
333                        else
334                        {
335                            // Left
336                            float position = pos.y / pos.x + 1.0f;
337                            it->second.panel_->setPosition(0.0f, (position - it->second.panel_->getWidth()) * 0.5f);
338                            it->second.panel_->setUV(0.0f, 0.0f, 0.5f, 0.5f);
339                            it->second.text_->setLeft(it->second.panel_->getWidth() + 0.01f);
340                            it->second.text_->setTop((position - it->second.text_->getCharHeight()) * 0.5f);
341                        }
342                    }
343                    else
344                    {
345                        if (pos.y < -pos.x)
346                        {
347                            // Bottom
348                            float position = -pos.x / pos.y + 1.0f;
349                            it->second.panel_->setPosition((position - it->second.panel_->getWidth()) * 0.5f, 1.0f - it->second.panel_->getHeight());
350                            it->second.panel_->setUV(0.0f, 0.5f, 0.5f, 1.0f );
351                            it->second.text_->setLeft((position - textLength) * 0.5f);
352                            it->second.text_->setTop(1.0f - it->second.panel_->getHeight() - it->second.text_->getCharHeight());
353                        }
354                        else
355                        {
356                            // Right
357                            float position = -pos.y / pos.x + 1.0f;
358                            it->second.panel_->setPosition(1.0f - it->second.panel_->getWidth(), (position - it->second.panel_->getHeight()) * 0.5f);
359                            it->second.panel_->setUV(0.5f, 0.5f, 1.0f, 1.0f);
360                            it->second.text_->setLeft(1.0f - it->second.panel_->getWidth() - textLength - 0.01f);
361                            it->second.text_->setTop((position - it->second.text_->getCharHeight()) * 0.5f);
362                        }
363                    }
364                }
365                else
366                {
367                    // Object is in view
368
369
370
371
372                    //calculate the health of the actual selected radarViewable (relativHealthScale: while (0) is no health left, (1) is the initial health)
373                    Pawn* pawnPtr = (Pawn*) (it->first->getWorldEntity());
374                    float health = pawnPtr->getHealth();
375                    float initHealth = pawnPtr->getMaxHealth();
376                    float relativHealthScale = health/initHealth;
377
378                    //integer values from 0 to 10 (0 is no health and 10 is full health)
379                    int discreteHealthScale = (int)(10*relativHealthScale);
380
381                    //calculate the HealthLevel (= OponentLevel or Strength) there are 5 Levels
382                    //Level 1, Level 2,... , Level 5
383                    int HealthLevel = 1;
384
385                    if(initHealth < 200)
386                        HealthLevel = 1;
387                    if(200 <= initHealth && initHealth < 500)
388                        HealthLevel = 2;
389                    if(500 <= initHealth && initHealth < 1000)
390                        HealthLevel = 3;
391                    if(1000 <= initHealth && initHealth < 2500)
392                        HealthLevel = 4;
393                    if(2500 <= initHealth)
394                        HealthLevel = 5;
395
396
397
398                    // Change material only if outOfView changed
399                    if (it->second.wasOutOfView_)
400                    {
401                        //it->second.panel_->setMaterialName("Orxonox/NavTDC");
402                        it->second.panel_->setMaterialName(TextureGenerator::getMaterialName("tdc.png", it->first->getRadarObjectColour()));
403                        it->second.panel_->setDimensions(this->navMarkerSize_ * this->getActualSize().x, this->navMarkerSize_ * this->getActualSize().y);
404                        it->second.target_->setDimensions(this->aimMarkerSize_ * this->getActualSize().x, this->aimMarkerSize_ * this->getActualSize().y);
405
406
407                        //it->second.health_->setMaterialName(TextureGenerator::getMaterialName("bar2_1.png", it->first->getRadarObjectColour()));
408                        it->second.health_->setMaterialName(TextureGenerator::getMaterialName("barSquare.png", it->first->getRadarObjectColour()));
409                        it->second.health_->setDimensions(this->healthMarkerSize_ * this->getActualSize().x , 0.75f*this->healthMarkerSize_ * this->getActualSize().y);
410                        it->second.wasOutOfView_ = false;
411
412                        // because as soon as relative health drops below 10% (0.1) the descrete value is 0 but as long as the
413                        // spaceship is still intact there should be at least one part of the bar left.
414                        if(1<=discreteHealthScale){
415                            it->second.health_->setTiling((float)discreteHealthScale , 1 ,0);
416                            it->second.health_->setDimensions(this->healthMarkerSize_ * this->getActualSize().x *0.1f*discreteHealthScale, 0.75f*this->healthMarkerSize_ * this->getActualSize().y);
417                        }
418
419
420
421                        //healthLevel
422                        it->second.healthLevel_->setMaterialName(TextureGenerator::getMaterialName("barSquare.png", it->first->getRadarObjectColour()));
423                        it->second.healthLevel_->setDimensions(this->healthLevelMarkerSize_ * this->getActualSize().x , 0.75f*this->healthLevelMarkerSize_ * this->getActualSize().y);
424                        it->second.wasOutOfView_ = false;
425                        it->second.healthLevel_->setTiling((float)HealthLevel , 1 ,0);
426                        it->second.healthLevel_->setDimensions(this->healthLevelMarkerSize_ * this->getActualSize().x *0.1f*HealthLevel, 0.25f*this->healthLevelMarkerSize_ * this->getActualSize().y);
427                    }
428
429
430
431                    // sets Position and Dimensions (amount) health
432                    it->second.health_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
433                    it->second.health_->setLeft((pos.x + 0.975f - it->second.panel_->getWidth()) * 0.5f);
434                    it->second.health_->setTop((-pos.y + 1.04f - it->second.panel_->getHeight()) * 0.5f);
435
436
437                    // because as soon as relative health drops below 10% (0.1) the descrete value is 0 but as long as the
438                    // spaceship is still intact there should be at least one part of the bar left.
439                    if(1<=discreteHealthScale){
440                    it->second.health_->setTiling((float)discreteHealthScale , 1 ,0);
441                    it->second.health_->setDimensions(this->healthMarkerSize_ * this->getActualSize().x *0.1f*discreteHealthScale, 0.75f*this->healthMarkerSize_ * this->getActualSize().y);
442                    }
443
444
445                    //sets Position and Dimensions (level) of healthLevel
446                    it->second.healthLevel_->setMaterialName(TextureGenerator::getMaterialName("barSquare.png", it->first->getRadarObjectColour()));
447                    it->second.healthLevel_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
448                    it->second.healthLevel_->setLeft((pos.x + 0.975f - it->second.panel_->getWidth()) * 0.5f);
449                    it->second.healthLevel_->setTop((-pos.y + 1.125f - it->second.panel_->getHeight()) * 0.5f);
450
451                    it->second.healthLevel_->setTiling((float)HealthLevel , 1 ,0);
452                    it->second.healthLevel_->setDimensions(this->healthLevelMarkerSize_ * this->getActualSize().x *0.1f*HealthLevel, 0.25f*this->healthLevelMarkerSize_ * this->getActualSize().y);
453
454
455                    // Position marker
456                    it->second.panel_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
457                    it->second.panel_->setLeft((pos.x + 1.0f - it->second.panel_->getWidth()) * 0.5f);
458                    it->second.panel_->setTop((-pos.y + 1.0f - it->second.panel_->getHeight()) * 0.5f);
459
460                    // Position text
461                    it->second.text_->setLeft((pos.x + 1.0f + it->second.panel_->getWidth()) * 0.5f);
462                    it->second.text_->setTop((-pos.y + 1.0f + it->second.panel_->getHeight()) * 0.5f);
463
464
465
466
467                    // Make sure the overlays are shown
468                    it->second.health_->show();
469                    it->second.healthLevel_->show();
470                    it->second.panel_->show();
471                    it->second.text_->show();
472
473                    // Target marker
474                    const Pawn* pawn = dynamic_cast<const Pawn*>(it->first->getWorldEntity());
475                    /* Pawn* humanPawn = HumanController::getLocalControllerEntityAsPawn();*/
476                    if(!it->second.selected_
477                            || it->first->getRVVelocity().squaredLength() == 0
478                            || pawn == NULL
479                            /* TODO : improve getTeam in such a way that it works
480                             * || humanPawn == NULL
481                             * || pawn->getTeam() == humanPawn->getTeam()*/)
482                    {
483                        // don't show marker for not selected enemies nor if the selected doesn't move
484                        it->second.target_->hide();
485                    }
486                    else // object is selected and moves
487                    {
488                        // get the aim position
489                        const Vector3& targetPos = this->toAimPosition(it->first);
490                        // Transform to screen coordinates
491                        Vector3 screenPos = camTransform * targetPos;
492                        // Check if the target marker is in view too
493                        if(screenPos.z > 1 || screenPos.x < -1.0 || screenPos.x > 1.0
494                                || screenPos.y < -1.0 || screenPos.y > 1.0)
495                        {
496                            it->second.target_->hide();
497                        }
498                        else
499                        {
500                            it->second.target_->setLeft((screenPos.x + 1.0f - it->second.target_->getWidth()) * 0.5f);
501                            it->second.target_->setTop((-screenPos.y + 1.0f - it->second.target_->getHeight()) * 0.5f);
502                            it->second.target_->show();
503                        }
504                    }
505
506                }
507            }
508            else // do not display on HUD
509
510            {
511                it->second.health_->hide();
512                it->second.healthLevel_->hide();
513                it->second.panel_->hide();
514                it->second.text_->hide();
515                it->second.target_->hide();
516            }
517        }
518
519        this->closestTarget_ = false;
520        this->nextTarget_ = false;
521    }
522
523    /** Overridden method of OrxonoxOverlay.
524     @details
525     Usually the entire overlay scales with scale().
526     Here we obviously have to adjust this.
527     */
528    void HUDNavigation::sizeChanged()
529    {
530        // Use size to compensate for aspect ratio if enabled.
531        float xScale = this->getActualSize().x;
532        float yScale = this->getActualSize().y;
533
534        for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it != this->activeObjectList_.end(); ++it)
535        {
536            if (it->second.health_ != NULL)
537                it->second.health_->setDimensions(this->healthMarkerSize_ * xScale, this->healthMarkerSize_ * yScale);
538            if (it->second.healthLevel_ != NULL)
539                it->second.healthLevel_->setDimensions(this->healthLevelMarkerSize_ * xScale, this->healthLevelMarkerSize_ * yScale);
540            if (it->second.panel_ != NULL)
541                it->second.panel_->setDimensions(this->navMarkerSize_ * xScale, this->navMarkerSize_ * yScale);
542            if (it->second.text_ != NULL)
543                it->second.text_->setCharHeight(this->textSize_ * yScale);
544            if (it->second.target_ != NULL)
545                it->second.target_->setDimensions(this->aimMarkerSize_ * xScale, this->aimMarkerSize_ * yScale);
546        }
547    }
548
549    void HUDNavigation::addObject(RadarViewable* object)
550    {
551        if (showObject(object) == false)
552        return;
553
554        if (this->activeObjectList_.size() >= this->markerLimit_)
555        if (object == NULL)
556        return;
557
558        // Object hasn't been added yet (we know that)
559        assert(this->activeObjectList_.find(object) == this->activeObjectList_.end());
560
561        // Scales used for dimensions and text size
562        float xScale = this->getActualSize().x;
563        float yScale = this->getActualSize().y;
564
565        // Create everything needed to display the object on the radar and add it to the map
566
567        // Create health
568        Ogre::PanelOverlayElement* health = static_cast<Ogre::PanelOverlayElement*>( Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "HUDNavigation_healthMarker_" + getUniqueNumberString()));
569        //panel->setMaterialName("Orxonox/NavTDC");
570        health->setMaterialName(TextureGenerator::getMaterialName("barSquare.png", object->getRadarObjectColour()));
571        health->setDimensions(this->healthMarkerSize_ * xScale, this->healthMarkerSize_ * yScale);
572        //panel->setColour(object->getRadarObjectColour());
573
574        // Create healthLevel
575        Ogre::PanelOverlayElement* healthLevel = static_cast<Ogre::PanelOverlayElement*>( Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "HUDNavigation_healthLevelMarker_" + getUniqueNumberString()));
576        //panel->setMaterialName("Orxonox/NavTDC");
577        health->setMaterialName(TextureGenerator::getMaterialName("barSquare.png", object->getRadarObjectColour()));
578        health->setDimensions(this->healthLevelMarkerSize_ * xScale, this->healthLevelMarkerSize_ * yScale);
579
580
581        // Create arrow/marker
582        Ogre::PanelOverlayElement* panel = static_cast<Ogre::PanelOverlayElement*>( Ogre::OverlayManager::getSingleton()
583                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
584        //panel->setMaterialName("Orxonox/NavTDC");
585        panel->setMaterialName(TextureGenerator::getMaterialName("tdc.png", object->getRadarObjectColour()));
586        panel->setDimensions(this->navMarkerSize_ * xScale, this->navMarkerSize_ * yScale);
587        //panel->setColour(object->getRadarObjectColour());
588
589        // Create target marker
590        Ogre::PanelOverlayElement* target = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
591                    .createOverlayElement("Panel", "HUDNavigation_targetMarker_" + getUniqueNumberString()));
592        target->setMaterialName(TextureGenerator::getMaterialName("target.png", object->getRadarObjectColour()));
593        target->setDimensions(this->aimMarkerSize_ * xScale, this->aimMarkerSize_ * yScale);
594
595        // Create text
596        Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*>( Ogre::OverlayManager::getSingleton()
597                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
598        text->setFontName(this->fontName_);
599        text->setCharHeight(this->textSize_ * yScale);
600        text->setColour(object->getRadarObjectColour());
601
602        health->hide();
603        healthLevel->hide();
604        panel->hide();
605        target->hide();
606        text->hide();
607
608        ObjectInfo tempStruct =
609        {   health, healthLevel, panel, target, text, false, false, false};
610        this->activeObjectList_[object] = tempStruct;
611
612        this->background_->addChild(health);
613        this->background_->addChild(healthLevel);
614        this->background_->addChild(panel);
615        this->background_->addChild(target);
616        this->background_->addChild(text);
617
618        this->sortedObjectList_.push_front(std::make_pair(object, (unsigned int)0));
619    }
620
621    void HUDNavigation::removeObject(RadarViewable* viewable)
622    {
623        std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.find(viewable);
624
625        if (this->activeObjectList_.find(viewable) != this->activeObjectList_.end())
626        {
627            // Detach overlays
628            this->background_->removeChild(it->second.health_->getName());
629            this->background_->removeChild(it->second.healthLevel_->getName());
630            this->background_->removeChild(it->second.panel_->getName());
631            this->background_->removeChild(it->second.target_->getName());
632            this->background_->removeChild(it->second.text_->getName());
633            // Properly destroy the overlay elements (do not use delete!)
634            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.health_);
635            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.healthLevel_);
636            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.panel_);
637            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.target_);
638            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.text_);
639            // Remove from the list
640            this->activeObjectList_.erase(viewable);
641        }
642
643        for (std::list<std::pair<RadarViewable*, unsigned int> >::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++listIt)
644        {
645            if ((listIt->first) == viewable)
646            {
647                this->sortedObjectList_.erase(listIt);
648                break;
649            }
650        }
651    }
652
653    void HUDNavigation::objectChanged(RadarViewable* viewable)
654    {
655        // TODO: niceification neccessary ;)
656        removeObject(viewable);
657        addObject(viewable);
658    }
659
660    bool HUDNavigation::showObject(RadarViewable* rv)
661    {
662        if (rv == orxonox_cast<RadarViewable*>(this->getOwner()))
663        return false;
664        assert(rv->getWorldEntity());
665        if (rv->getWorldEntity()->isVisible() == false || rv->getRadarVisibility() == false)
666        return false;
667        return true;
668    }
669
670    void HUDNavigation::changedOwner()
671    {
672        const std::set<RadarViewable*>& respawnObjects = this->getOwner()->getScene()->getRadar()->getRadarObjects();
673        for (std::set<RadarViewable*>::const_iterator it = respawnObjects.begin(); it != respawnObjects.end(); ++it)
674        {
675            if (!(*it)->isHumanShip_)
676            this->addObject(*it);
677        }
678    }
679
680    Vector3 HUDNavigation::toAimPosition(RadarViewable* target) const
681    {
682        Vector3 wePosition = HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition();
683        Vector3 targetPosition = target->getRVWorldPosition();
684        Vector3 targetSpeed = target->getRVVelocity();
685
686        return getPredictedPosition(wePosition, this->currentMunitionSpeed_, targetPosition, targetSpeed);
687    }
688
689    void HUDNavigation::selectClosestTarget()
690    {
691        if(HUDNavigation::localHUD_s)
692        {
693            HUDNavigation::localHUD_s->closestTarget_ = true;
694        }
695    }
696
697    void HUDNavigation::selectNextTarget()
698    {
699        if(HUDNavigation::localHUD_s)
700        {
701            HUDNavigation::localHUD_s->nextTarget_ = true;
702        }
703    }
704}
Note: See TracBrowser for help on using the repository browser.