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
RevLine 
[1505]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
[1454]4 *
[1505]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 *
[1454]22 *   Author:
23 *      Felix Schulthess
24 *   Co-authors:
[1590]25 *      Reto Grieder
[7801]26 *      Oliver Scheuss
[9016]27 *      Matthias Spalinger
[1454]28 *
29 */
[1393]30
[1601]31#include "HUDNavigation.h"
[1410]32
[6417]33#include <OgreCamera.h>
[7163]34#include <OgreFontManager.h>
[1393]35#include <OgreOverlayManager.h>
[1614]36#include <OgreTextAreaOverlayElement.h>
37#include <OgrePanelOverlayElement.h>
[1410]38
[9526]39#include <typeinfo>
40
[1614]41#include "util/Math.h"
[1616]42#include "util/Convert.h"
[9526]43#include "core/command/ConsoleCommand.h"
[1616]44#include "core/CoreIncludes.h"
45#include "core/XMLPort.h"
[6417]46#include "CameraManager.h"
[5929]47#include "Scene.h"
[5735]48#include "Radar.h"
[6417]49#include "graphics/Camera.h"
50#include "controllers/HumanController.h"
51#include "worldentities/pawns/Pawn.h"
[7163]52#include "worldentities/WorldEntity.h"
[9667]53#include "core/config/ConfigValueIncludes.h"
[7163]54#include "tools/TextureGenerator.h"
55// #include <boost/bind/bind_template.hpp>
[1393]56
[7163]57
[1393]58namespace orxonox
59{
[9526]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)
[9348]66    {
67        return a.second < b.second;
68    }
[9667]69    RegisterClass ( HUDNavigation );
[2087]70
[9526]71    HUDNavigation* HUDNavigation::localHUD_s = 0;
72
[9667]73    HUDNavigation::HUDNavigation(Context* context) :
74        OrxonoxOverlay(context)
[9348]75    {
[9939]76        RegisterObject(HUDNavigation);
77        this->setConfigValues();
[2087]78
[9348]79        // Set default values
80        this->setFont("Monofur");
81        this->setTextSize(0.05f);
[9526]82        this->setNavMarkerSize(0.03f);
83        this->setAimMarkerSize(0.02f);
[10149]84        this->setHealthMarkerSize(0.06f);
[9526]85
[9348]86        this->setDetectionLimit(10000.0f);
[9526]87        this->currentMunitionSpeed_ = 2500.0f;
88
89        this->closestTarget_ = true;
90        this->nextTarget_ = false;
91        HUDNavigation::localHUD_s = this;
[9348]92    }
[2087]93
[9348]94    HUDNavigation::~HUDNavigation()
95    {
96        if (this->isInitialized())
97        {
98            for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it != this->activeObjectList_.end();)
[9526]99            removeObject((it++)->first);
[9348]100        }
101        this->sortedObjectList_.clear();
102    }
[2087]103
[9348]104    void HUDNavigation::setConfigValues()
105    {
106        SetConfigValue(markerLimit_, 3);
107        SetConfigValue(showDistance_, false);
108    }
[2087]109
[9348]110    void HUDNavigation::XMLPort(Element& xmlelement, XMLPort::Mode mode)
[7163]111    {
[9348]112        SUPER(HUDNavigation, XMLPort, xmlelement, mode);
[2087]113
[9526]114        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlelement, mode);
115        XMLPortParam(HUDNavigation, "textSize", setTextSize, getTextSize, xmlelement, mode);
116        XMLPortParam(HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlelement, mode);
[9348]117        XMLPortParam(HUDNavigation, "detectionLimit", setDetectionLimit, getDetectionLimit, xmlelement, mode);
[9526]118        XMLPortParam(HUDNavigation, "aimMarkerSize", setAimMarkerSize, getAimMarkerSize, xmlelement, mode);
[10122]119        XMLPortParam(HUDNavigation, "healthMarkerSize", setHealthMarkerSize, getHealthMarkerSize, xmlelement, mode);
120
[1393]121    }
122
[9348]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)
[9526]135            it->second.text_->setFontName(this->fontName_);
[9348]136        }
137    }
[1564]138
[9348]139    const std::string& HUDNavigation::getFont() const
[1590]140    {
[9348]141        return this->fontName_;
[1590]142    }
[9348]143
144    void HUDNavigation::setTextSize(float size)
[1590]145    {
[9348]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_)
[9526]155            it->second.text_->setCharHeight(size);
[9348]156        }
[1590]157    }
158
[9348]159    float HUDNavigation::getTextSize() const
[1590]160    {
[9348]161        return this->textSize_;
[1590]162    }
[9348]163
164    float HUDNavigation::getArrowSizeX(int dist) const
[7163]165    {
[9348]166        if (dist < 600)
[9526]167        dist = 600;
[9348]168        return this->getActualSize().x * 900 * this->navMarkerSize_ / dist;
[7163]169    }
[1590]170
[9348]171    float HUDNavigation::getArrowSizeY(int dist) const
[1590]172    {
[9348]173        if (dist < 600)
[9526]174        dist = 600;
[9348]175        return this->getActualSize().y * 900 * this->navMarkerSize_ / dist;
[1590]176    }
177
[9348]178    void HUDNavigation::tick(float dt)
[1590]179    {
[9348]180        SUPER(HUDNavigation, tick, dt);
[1400]181
[9348]182        Camera* cam = CameraManager::getInstance().getActiveCamera();
183        if (cam == NULL)
[9526]184        return;
[9348]185        const Matrix4& camTransform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
[1399]186
[9348]187        for (std::list<std::pair<RadarViewable*, unsigned int> >::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++listIt)
[9526]188        listIt->second = (int)((listIt->first->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f);
[1564]189
[9348]190        this->sortedObjectList_.sort(compareDistance);
[9016]191
[9348]192        unsigned int markerCount = 0;
193        bool closeEnough = false; // only display objects that are close enough to be relevant for the player
[1399]194
[9526]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
[9348]209        for (std::list<std::pair<RadarViewable*, unsigned int> >::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++markerCount, ++listIt)
210        {
[10122]211
[9348]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
[9526]215            if (markerCount < this->markerLimit_ && (closeEnough || this->detectionLimit_ < 0))
[1580]216            {
[9348]217                // Get Distance to HumanController and save it in the TextAreaOverlayElement.
218                int dist = listIt->second;
219                float textLength = 0.0f;
[1590]220
[9348]221                if (this->showDistance_)
[1580]222                {
[9348]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;
[1399]226                }
[9348]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                }
[7163]233
[9526]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
[10122]281
282
[9348]283                // Transform to screen coordinates
284                Vector3 pos = camTransform * it->first->getRVWorldPosition();
[9016]285
[9348]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;
[9016]298
[9348]299                if (outOfView)
[7163]300                {
[9348]301                    // Object is not in view
302
303                    // Change material only if outOfView changed
304                    if (!it->second.wasOutOfView_)
[7163]305                    {
[10110]306                        it->second.health_->hide();
307                        it->second.panel_->setMaterialName(TextureGenerator::getMaterialName("arrows.png", it->first->getRadarObjectColour()));
[9348]308                        it->second.wasOutOfView_ = true;
[9526]309                        it->second.target_->hide();
[7163]310                    }
[9348]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                    }
[7163]340                    else
341                    {
[9348]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                        }
[7163]360                    }
361                }
[1580]362                else
363                {
[9348]364                    // Object is in view
[7163]365
[10122]366
367
368
[10149]369                        //calculate the health of the actual selected radarViewable (while (0) is no health left, (1) is the initial health)
[10122]370
[10149]371                    Pawn* pawnPtr = (Pawn*) (it->first->getWorldEntity());
372                    float health = pawnPtr->getHealth();
373                    float initHealth = pawnPtr->getMaxHealth();
374                    float relativHealthScale = health/initHealth;
[10122]375
[10149]376                    //values from 0 to 10
377                    int discreteHealthScale = 10*relativHealthScale;
[10143]378
[10149]379
380
[10122]381                        // Change material only if outOfView changed
[9348]382                    if (it->second.wasOutOfView_)
[7163]383                    {
[9348]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);
[9526]387                        it->second.target_->setDimensions(this->aimMarkerSize_ * this->getActualSize().x, this->aimMarkerSize_ * this->getActualSize().y);
[10110]388
[10143]389                        //
[10149]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);
[9348]393                        it->second.wasOutOfView_ = false;
[10149]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                        }
[7163]399                    }
[9348]400
[10122]401
402
[10143]403                    // Position and Dimensions (amount) health
[10122]404                    it->second.health_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
[10143]405                    it->second.health_->setLeft((pos.x + 0.975f - it->second.panel_->getWidth()) * 0.5f);
[10149]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);
[10110]408
409
[10149]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
[9348]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);
[9526]425
426                    // Make sure the overlays are shown
[10110]427
428                    it->second.health_->show();
[9526]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
[1411]466                }
467            }
[9348]468            else // do not display on HUD
[9526]469
[1580]470            {
[10122]471                it->second.health_->hide();
[9348]472                it->second.panel_->hide();
473                it->second.text_->hide();
[9526]474                it->second.target_->hide();
[9348]475            }
476        }
[9526]477
478        this->closestTarget_ = false;
479        this->nextTarget_ = false;
[9348]480    }
[7163]481
[9348]482    /** Overridden method of OrxonoxOverlay.
[9526]483     @details
484     Usually the entire overlay scales with scale().
485     Here we obviously have to adjust this.
486     */
[9348]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;
[7163]492
[9348]493        for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it != this->activeObjectList_.end(); ++it)
[1580]494        {
[10110]495                if (it->second.health_ != NULL)
496                    it->second.health_->setDimensions(this->healthMarkerSize_ * xScale, this->healthMarkerSize_ * yScale);
[9348]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);
[9526]501            if (it->second.target_ != NULL)
502                it->second.target_->setDimensions(this->aimMarkerSize_ * xScale, this->aimMarkerSize_ * yScale);
[7163]503        }
504    }
[1566]505
[9348]506    void HUDNavigation::addObject(RadarViewable* object)
[7163]507    {
[9348]508        if (showObject(object) == false)
[9526]509        return;
[7163]510
[9348]511        if (this->activeObjectList_.size() >= this->markerLimit_)
[9526]512        if (object == NULL)
513        return;
[7163]514
[9348]515        // Object hasn't been added yet (we know that)
516        assert(this->activeObjectList_.find(object) == this->activeObjectList_.end());
[7163]517
[9348]518        // Scales used for dimensions and text size
519        float xScale = this->getActualSize().x;
520        float yScale = this->getActualSize().y;
[7163]521
[9348]522        // Create everything needed to display the object on the radar and add it to the map
[10149]523
[10110]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");
[10149]528                health->setMaterialName(TextureGenerator::getMaterialName("barSquare.png", object->getRadarObjectColour()));
[10110]529                health->setDimensions(this->healthMarkerSize_ * xScale, this->healthMarkerSize_ * yScale);
530                //panel->setColour(object->getRadarObjectColour());
[7163]531
[10110]532
[9348]533        // Create arrow/marker
534        Ogre::PanelOverlayElement* panel = static_cast<Ogre::PanelOverlayElement*>( Ogre::OverlayManager::getSingleton()
[9526]535                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
[9348]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());
[7163]540
[9526]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
[9348]548        Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*>( Ogre::OverlayManager::getSingleton()
[9526]549                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
[9348]550        text->setFontName(this->fontName_);
551        text->setCharHeight(text->getCharHeight() * yScale);
552        text->setColour(object->getRadarObjectColour());
[7163]553
[10110]554        health->hide();
[9348]555        panel->hide();
[9526]556        target->hide();
[9348]557        text->hide();
[7163]558
[9526]559        ObjectInfo tempStruct =
[10122]560        {   health, panel, target, text, false, false, false};
[9348]561        this->activeObjectList_[object] = tempStruct;
[7163]562
[10110]563        this->background_->addChild(health);
[9348]564        this->background_->addChild(panel);
[9526]565        this->background_->addChild(target);
[9348]566        this->background_->addChild(text);
[7163]567
[9348]568        this->sortedObjectList_.push_front(std::make_pair(object, (unsigned int)0));
569    }
[7163]570
[9348]571    void HUDNavigation::removeObject(RadarViewable* viewable)
[1580]572    {
[9348]573        std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.find(viewable);
[7163]574
[9348]575        if (this->activeObjectList_.find(viewable) != this->activeObjectList_.end())
576        {
577            // Detach overlays
[10110]578                this->background_->removeChild(it->second.health_->getName());
[9348]579            this->background_->removeChild(it->second.panel_->getName());
[9526]580            this->background_->removeChild(it->second.target_->getName());
[9348]581            this->background_->removeChild(it->second.text_->getName());
582            // Properly destroy the overlay elements (do not use delete!)
[10110]583            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.health_);
[9348]584            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.panel_);
[9526]585            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.target_);
[9348]586            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.text_);
587            // Remove from the list
588            this->activeObjectList_.erase(viewable);
589        }
[7163]590
[9348]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        }
[1410]599    }
[1590]600
[9348]601    void HUDNavigation::objectChanged(RadarViewable* viewable)
[1590]602    {
[9348]603        // TODO: niceification neccessary ;)
604        removeObject(viewable);
605        addObject(viewable);
606    }
[7163]607
[9348]608    bool HUDNavigation::showObject(RadarViewable* rv)
609    {
610        if (rv == orxonox_cast<RadarViewable*>(this->getOwner()))
[9526]611        return false;
[9348]612        assert(rv->getWorldEntity());
613        if (rv->getWorldEntity()->isVisible() == false || rv->getRadarVisibility() == false)
[9526]614        return false;
[9348]615        return true;
[1590]616    }
[7163]617
[9348]618    void HUDNavigation::changedOwner()
[7163]619    {
[9348]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_)
[9526]624            this->addObject(*it);
[9348]625        }
[7163]626    }
[9526]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    }
[7163]657}
Note: See TracBrowser for help on using the repository browser.