Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/hudHS14/src/modules/overlays/hud/HUDNavigation.cc @ 10156

Last change on this file since 10156 was 10149, checked in by aejonas, 10 years ago

the healthbar is now changing its size every thime the spaceship loses one tenth of the initial health

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