Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/hudelements/src/modules/overlays/hud/HUDNavigation.cc @ 6914

Last change on this file since 6914 was 6914, checked in by sfluecki, 14 years ago

changed pair in HUDNavigation activeObjectListMap to Struct

  • Property svn:eol-style set to native
File size: 15.8 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
[1454]26 *
27 */
[1393]28
[1601]29#include "HUDNavigation.h"
[6865]30#include <utility>
[1410]31
[3196]32#include <string>
[6417]33#include <OgreCamera.h>
[1393]34#include <OgreOverlayManager.h>
[1614]35#include <OgreTextAreaOverlayElement.h>
36#include <OgrePanelOverlayElement.h>
37#include "util/Math.h"
[1616]38#include "util/Convert.h"
39#include "core/CoreIncludes.h"
40#include "core/XMLPort.h"
[6417]41#include "CameraManager.h"
[5929]42#include "Scene.h"
[5735]43#include "Radar.h"
[6417]44#include "graphics/Camera.h"
45#include "controllers/HumanController.h"
46#include "worldentities/pawns/Pawn.h"
[6849]47#include "worldentities/WorldEntity.h"
[6897]48#include "interfaces/RadarViewable.h"
[1393]49
50namespace orxonox
51{
[6874]52CreateFactory(HUDNavigation);
[1590]53
[6874]54HUDNavigation::HUDNavigation(BaseObject* creator)
[2087]55        : OrxonoxOverlay(creator)
[6874]56{
57    RegisterObject(HUDNavigation);
[6897]58
59    setFont("Monofur");
60    setTextSize(0.05f);
61    setNavMarkerSize(0.05f);
62
63
[6886]64   
[6865]65//         // create nav text
66//         navText_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
67//             .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
[6874]68//
[6865]69//         // create nav marker
70//         navMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
71//             .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
72//         navMarker_->setMaterialName("Orxonox/NavArrows");
[2087]73
[6897]74        /*
75                // create aim marker
76                aimMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
77                    .createOverlayElement("Panel", "HUDNavigation_aimMarker_" + getUniqueNumberString()));
78                aimMarker_->setMaterialName("Orxonox/NavCrosshair");
79                this->wasOutOfView_ = true; // Ensure the material is changed right the first time..
[2087]80
[6868]81
[6897]82        */
83        /*
84                background_->addChild(navMarker_);*/
[6417]85//        background_->addChild(aimMarker_);
[6865]86//         background_->addChild(navText_);
[2087]87
[6897]88        // hide at first
[6865]89//         this->setVisible(false);
[6874]90
91
[6897]92
[6868]93//         setAimMarkerSize(0.04f);
[6897]94   
[6874]95}
[1393]96
[6897]97HUDNavigation::~HUDNavigation() {
[6874]98
99    if (this->isInitialized())
[1564]100    {
[6899]101        activeObjectListType::iterator it;
[6914]102        for( it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it )
[6899]103        {
[6914]104            removeObject(it->first);
[6899]105        }
[6897]106        activeObjectList_.clear();
[1564]107    }
[6874]108}
[1564]109
[6897]110void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode) {
[6874]111    SUPER(HUDNavigation, XMLPort, xmlElement, mode);
[1394]112
[6874]113    XMLPortParam(HUDNavigation, "font",     setFont,     getFont,     xmlElement, mode);
114    XMLPortParam(HUDNavigation, "textSize", setTextSize, getTextSize, xmlElement, mode);
115    XMLPortParam(HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
[6417]116//        XMLPortParam(HUDNavigation, "aimMarkerSize", setAimMarkerSize, getAimMarkerSize, xmlElement, mode);
[6874]117}
[1393]118
[6874]119void HUDNavigation::setFont(const std::string& font)
120{
121    fontName_ = font;
122    if (!activeObjectList_.empty())
[1590]123    {
[6874]124        for (tempRadarViewable = activeObjectList_.begin(); tempRadarViewable!=activeObjectList_.end(); ++tempRadarViewable)
125        {
[6914]126            if (tempRadarViewable->second.text_ && !fontName_.empty())
127                tempRadarViewable->second.text_->setFontName(fontName_);
[6874]128        }
[1590]129    }
[6874]130}
[1590]131
[6874]132const std::string& HUDNavigation::getFont() const
133{
134    return fontName_;
135}
[1590]136
[6874]137void HUDNavigation::setTextSize(float size)
138{
139    textSize_ = size;
140    if (!activeObjectList_.empty())
[1590]141    {
[6874]142        for (tempRadarViewable = activeObjectList_.begin(); tempRadarViewable!=activeObjectList_.end(); ++tempRadarViewable)
143        {
[6914]144            if (tempRadarViewable->second.text_ && size >= 0.0f)
145                tempRadarViewable->second.text_->setCharHeight(size);
[6874]146        }
[1590]147    }
[6874]148}
[1590]149
[6874]150float HUDNavigation::getTextSize() const
151{
152    return textSize_;
153}
[1590]154
[6874]155void HUDNavigation::tick(float dt)
156{
157    SUPER(HUDNavigation, tick, dt);
158
[6865]159//      updateActiveObjectList(activeObjectList_);
[2662]160
[6874]161    // Get radar
[6865]162//         Radar* radar = this->getOwner()->getScene()->getRadar();
[6874]163//
[6865]164//         if (!radar->getFocus())
165//         {
166//             this->overlay_->hide();
167//             return;
168//         }
169//         else
170//         {
171//             this->overlay_->show();
172//         }
[5929]173
[6874]174    // set text
[6865]175//         int dist = static_cast<int>(getDist2Focus());
176//         navText_->setCaption(multi_cast<std::string>(dist));
177//         float textLength = multi_cast<std::string>(dist).size() * navText_->getCharHeight() * 0.3f;
[1399]178
[6899]179    if (!activeObjectList_.empty())
180    {
[6874]181        for (tempRadarViewable = activeObjectList_.begin(); tempRadarViewable!=activeObjectList_.end(); ++tempRadarViewable)
[1590]182        {
[1399]183
[6898]184
[6874]185            //get Distance to HumanController and save it in the TextAreaOverlayElement.
186            int dist = (int)(tempRadarViewable->first->getRVWorldPosition() - HumanController::getLocalControllerEntityAsPawn()->getWorldPosition()).length();
[6914]187            tempRadarViewable->second.text_->setCaption(multi_cast<std::string>(dist));
188            float textLength = multi_cast<std::string>(dist).size() * tempRadarViewable->second.text_->getCharHeight() * 0.3f;
[1411]189
[6874]190
[6898]191
[6874]192            orxonox::Camera* cam = CameraManager::getInstance().getActiveCamera();
193            if (!cam)
194                return;
195            const Matrix4& transform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
196            // transform to screen coordinates
197            Vector3 pos = transform * tempRadarViewable->first->getRVWorldPosition();
198
199
[6898]200
[6914]201
[6874]202            if (pos.z > 1.0)
[1580]203            {
[6874]204                // z > 1.0 means that the object is behind the camera
[6914]205                tempRadarViewable->second.outOfView_ = true;
[6874]206                // we have to switch all coordinates (if you don't know why,
207                // try linear algebra lectures, because I can't explain..)
208                pos.x = -pos.x;
209                pos.y = -pos.y;
[1411]210            }
[6874]211            else
[6914]212                tempRadarViewable->second.outOfView_ = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
[1590]213
[6914]214            if (tempRadarViewable->second.outOfView_)
[1580]215            {
[6874]216                // object is not in view
217//            aimMarker_->hide();
218
[6914]219                if (!tempRadarViewable->second.wasOutOfView__)
[1580]220                {
[6914]221                    tempRadarViewable->second.panel_->setMaterialName("Orxonox/NavArrows");
222                    tempRadarViewable->second.wasOutOfView__ = true;
[1399]223                }
[6874]224
225
[6898]226
[6874]227                if (pos.x < pos.y)
228                {
229                    if (pos.y > -pos.x)
230                    {
231                        // up
232                        float position = pos.x / pos.y + 1.0f;
[6914]233                        tempRadarViewable->second.panel_->setPosition((position - tempRadarViewable->second.panel_->getWidth()) * 0.5f, 0.0f);
234                        tempRadarViewable->second.panel_->setUV(0.5f, 0.0f, 1.0f, 0.5f);
235                        tempRadarViewable->second.text_->setLeft((position - textLength) * 0.5f);
236                        tempRadarViewable->second.text_->setTop(tempRadarViewable->second.panel_->getHeight());
[6874]237                    }
238                    else
239                    {
240                        // left
241                        float position = pos.y / pos.x + 1.0f;
[6914]242                        tempRadarViewable->second.panel_->setPosition(0.0f, (position - tempRadarViewable->second.panel_->getWidth()) * 0.5f);
243                        tempRadarViewable->second.panel_->setUV(0.0f, 0.0f, 0.5f, 0.5f);
244                        tempRadarViewable->second.text_->setLeft(tempRadarViewable->second.panel_->getWidth() + 0.01f);
245                        tempRadarViewable->second.text_->setTop((position - tempRadarViewable->second.text_->getCharHeight()) * 0.5f);
[6874]246                    }
247                }
[1580]248                else
249                {
[6875]250
[6874]251                    if (pos.y < -pos.x)
252                    {
253                        // down
254                        float position = -pos.x / pos.y + 1.0f;
[6914]255                        tempRadarViewable->second.panel_->setPosition((position - tempRadarViewable->second.panel_->getWidth()) * 0.5f, 1.0f - tempRadarViewable->second.panel_->getHeight());
256                        tempRadarViewable->second.panel_->setUV(0.0f, 0.5f, 0.5f, 1.0f);
257                        tempRadarViewable->second.text_->setLeft((position - textLength) * 0.5f);
258                        tempRadarViewable->second.text_->setTop(1.0f - tempRadarViewable->second.panel_->getHeight() - tempRadarViewable->second.text_->getCharHeight());
[6874]259                    }
260                    else
261                    {
262                        // right
263                        float position = -pos.y / pos.x + 1.0f;
[6914]264                        tempRadarViewable->second.panel_->setPosition(1.0f - tempRadarViewable->second.panel_->getWidth(), (position - tempRadarViewable->second.panel_->getHeight()) * 0.5f);
265                        tempRadarViewable->second.panel_->setUV(0.5f, 0.5f, 1.0f, 1.0f);
266                        tempRadarViewable->second.text_->setLeft(1.0f - tempRadarViewable->second.panel_->getWidth() - textLength - 0.01f);
267                        tempRadarViewable->second.text_->setTop((position - tempRadarViewable->second.text_->getCharHeight()) * 0.5f);
[6874]268                    }
[1411]269                }
270            }
[1590]271            else
[1580]272            {
[6874]273
[6898]274
[6874]275                // object is in view
276                /*
277                            Vector3 aimpos = transform * getPredictedPosition(SpaceShip::getLocalShip()->getPosition(),
278                                    Projectile::getSpeed(), Radar::getInstance().getFocus()->getRVWorldPosition(), Radar::getInstance().getFocus()->getRVOrientedVelocity());
279                */
[6914]280                if (tempRadarViewable->second.wasOutOfView_)
[1580]281                {
[6914]282                    tempRadarViewable->second.panel_->setMaterialName("Orxonox/NavTDC");
283                    tempRadarViewable->second.wasOutOfView__ = false;
[1399]284                }
[1590]285
[6874]286                // object is in view
[6914]287                tempRadarViewable->second.panel_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
288                tempRadarViewable->second.panel_->setLeft((pos.x + 1.0f - tempRadarViewable->second.panel_->getWidth()) * 0.5f);
289                tempRadarViewable->second.panel_->setTop((-pos.y + 1.0f - tempRadarViewable->second.panel_->getHeight()) * 0.5f);
[1566]290
[6886]291
292//                 aimMarker_->show();
293//                 aimMarker_->setLeft((aimpos.x + 1.0f - aimMarker_->getWidth()) * 0.5f);
294//                 aimMarker_->setTop((-aimpos.y + 1.0f - aimMarker_->getHeight()) * 0.5f);
295//
[6914]296                tempRadarViewable->second.text_->setLeft((pos.x + 1.0f + tempRadarViewable->second.panel_->getWidth()) * 0.5f);
297                tempRadarViewable->second.text_->setTop((-pos.y + 1.0f + tempRadarViewable->second.panel_->getHeight()) * 0.5f);
[6874]298            }
[6875]299
[6914]300            tempRadarViewable->second.panel_->show();
301            tempRadarViewable->second.text_->show();
302//             tempRadarViewable->second.text_->hide();
[6897]303        }
304
[1410]305    }
[6886]306
[6874]307}
[1590]308
[6873]309
[6898]310// float HUDNavigation::getDist2Focus() const {
311//
312//     Radar* radar = this->getOwner()->getScene()->getRadar();
313//     if (radar->getFocus() && HumanController::getLocalControllerEntityAsPawn())
314//         return (radar->getFocus()->getRVWorldPosition() - HumanController::getLocalControllerEntityAsPawn()->getWorldPosition()).length();
315//     else
316//         return 0;
317// }
[6874]318
319/**
320@brief Overridden method of OrxonoxOverlay. Usually the entire overlay
321       scales with scale(). Here we obviously have to adjust this.
322*/
[6899]323void HUDNavigation::sizeChanged()
324{
[6874]325    // use size to compensate for aspect ratio if enabled.
326    float xScale = this->getActualSize().x;
327    float yScale = this->getActualSize().y;
328
329    if (!activeObjectList_.empty())
330    {
331        for (tempRadarViewable = activeObjectList_.begin(); tempRadarViewable!=activeObjectList_.end(); ++tempRadarViewable)
332        {
333
[6914]334            if (tempRadarViewable->second.panel_)
335                tempRadarViewable->second.panel_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
[6873]336//            if (this->aimMarker_)
337//            aimMarker_->setDimensions(aimMarkerSize_ * xScale, aimMarkerSize_ * yScale);
[6914]338            if (tempRadarViewable->second.text_)
339                tempRadarViewable->second.text_->setCharHeight(tempRadarViewable->second.text_->getCharHeight() * yScale);
[6874]340        }
[1590]341    }
[6874]342}
343
344
[6899]345void HUDNavigation::addObject(RadarViewable* object)
346{
[6874]347    if (object == dynamic_cast<RadarViewable*>(this->getOwner()))
348        return;
349
350    assert(object);
351
352    // Make sure the object hasn't been added yet
353    assert( this->activeObjectList_.find(object) == this->activeObjectList_.end() );
354
355    // Create everything needed to display the object on the radar and add it to the map
356
357    // create nav marker
358    Ogre::PanelOverlayElement* panel = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
359                                       .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
360
361    panel->setMaterialName("Orxonox/NavArrows");
362
363    Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
364                                         .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
[6898]365               
366   
[6880]367    float xScale = this->getActualSize().x;
368    float yScale = this->getActualSize().y;
[6849]369
[6880]370    panel->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
371    text->setCharHeight(text->getCharHeight() * yScale);
372
[6914]373    objectStruct tempStruct = {panel, text, true};
374    activeObjectList_[object] = tempStruct;
[6874]375
[6880]376    this->background_->addChild(panel);
377    this->background_->addChild(text);
378
[6865]379//      background_->addChild(activeObjectList_[object].first);
380//      background_->addChild(activeObjectList_[object].second);
[6898]381
[6874]382}
[6865]383
[6880]384void HUDNavigation::removeObject(RadarViewable* viewable)
385{
386    activeObjectListType::iterator it = activeObjectList_.find(viewable);
387
388    if (activeObjectList_.find(viewable) != activeObjectList_.end())
389    {
390        // Remove overlays from Ogre
[6914]391        this->background_->removeChild(it->second.panel_->getName());
392        this->background_->removeChild(it->second.text_->getName());
[6899]393        // correctly destroy the overlay elements
[6914]394        Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.panel_);
395        Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.text_);
[6880]396
397        activeObjectList_.erase(viewable);
398    }
[6874]399}
400
[6899]401void HUDNavigation::changedOwner()
402{
403    respawnObjectSetType respawnObjectSet = this->getOwner()->getScene()->getRadar()->getRadarObjects();
[6898]404    respawnObjectSetType::iterator respawnObjectSetIt_;
[6899]405    for (respawnObjectSetIt_ = respawnObjectSet.begin(); respawnObjectSetIt_ != respawnObjectSet.end(); ++respawnObjectSetIt_)
[6898]406    {
[6899]407        if (!(*respawnObjectSetIt_)->isHumanShip_)
408            this->addObject(*respawnObjectSetIt_);
[6898]409    }
410
411}
412
413
414
[6865]415//      void updateActiveObjectList(map activeObjectList_){}
[6874]416//
[6865]417//      void HUDNavigation::objectChanged(RadarViewable* viewable){}
[6874]418//
419//
[6849]420//         float HUDNavigation::getRadarSensitivity(){}
421//         void HUDNavigation::radarTick(float dt){}
[6796]422
[6874]423
[6865]424}
[6796]425
[6865]426
Note: See TracBrowser for help on using the repository browser.