Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

changes in 'src/modules/overlays/hud/HUDNavigation'.
HUDNavigation::changedOwner() now working for the case you get shot. all targetMarkers are now shown after you respawn. textOverlays still missing - why i dont know?.

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