Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/wagnis_HS18/src/modules/wagnis/WagnisHUD.cc @ 12136

Last change on this file since 12136 was 12136, checked in by kunzro, 5 years ago

HUD fixed

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