Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/wagnis/WagnisHUD.cc

Last change on this file was 12159, checked in by kunzro, 6 years ago

highlight and dehighlight function added for province and WagnisHUD info adjusts colour

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