Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/overlays/hud/HUDRadar.cc @ 8538

Last change on this file since 8538 was 7880, checked in by landauf, 14 years ago

radar doesn't abort if owner is missing
radar works with all ControllableEntities not just Pawns

  • Property svn:eol-style set to native
File size: 7.5 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 *      Yuning Chai
24 *      Felix Schulthess
25 *   Co-authors:
26 *      Reto Grieder
27 *
28 */
29
30#include "HUDRadar.h"
31
32#include <OgreOverlayManager.h>
33#include <OgrePanelOverlayElement.h>
34
35#include "util/Math.h"
36#include "util/StringUtils.h"
37#include "core/CoreIncludes.h"
38#include "core/XMLPort.h"
39#include "tools/TextureGenerator.h"
40#include "worldentities/ControllableEntity.h"
41#include "Scene.h"
42#include "Radar.h"
43
44namespace orxonox
45{
46    CreateFactory(HUDRadar);
47
48    HUDRadar::HUDRadar(BaseObject* creator)
49        : OrxonoxOverlay(creator)
50    {
51        RegisterObject(HUDRadar);
52
53        this->marker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
54            .createOverlayElement("Panel", "HUDRadar_marker_" + getUniqueNumberString()));
55        this->marker_->setMaterialName("Orxonox/RadarMarker");
56        this->overlay_->add2D(this->marker_);
57        this->marker_->hide();
58
59        this->setRadarSensitivity(1.0f);
60        this->setHalfDotSizeDistance(3000.0f);
61        this->setMaximumDotSize(0.1f);
62
63        this->shapeMaterials_[RadarViewable::Dot]      = "RadarDot.png";
64        this->shapeMaterials_[RadarViewable::Triangle] = "RadarTriangle.png";
65        this->shapeMaterials_[RadarViewable::Square]   = "RadarSquare.png";
66
67        this->owner_ = 0;
68    }
69
70    HUDRadar::~HUDRadar()
71    {
72        if (this->isInitialized())
73        {
74            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->marker_);
75            for (std::map<RadarViewable*,Ogre::PanelOverlayElement*>::iterator it = this->radarObjects_.begin();
76                it != this->radarObjects_.end(); ++it)
77            {
78                Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second);
79            }
80        }
81    }
82
83    void HUDRadar::XMLPort(Element& xmlelement, XMLPort::Mode mode)
84    {
85        SUPER(HUDRadar, XMLPort, xmlelement, mode);
86
87        XMLPortParam(HUDRadar, "sensitivity", setRadarSensitivity, getRadarSensitivity, xmlelement, mode);
88        XMLPortParam(HUDRadar, "halfDotSizeDistance", setHalfDotSizeDistance, getHalfDotSizeDistance, xmlelement, mode);
89        XMLPortParam(HUDRadar, "maximumDotSize", setMaximumDotSize, getMaximumDotSize, xmlelement, mode);
90    }
91
92    void HUDRadar::addObject(RadarViewable* object)
93    {
94        if (object == dynamic_cast<RadarViewable*>(this->owner_))
95            return;
96
97        // Make sure the object hasn't been added yet
98        assert( this->radarObjects_.find(object) == this->radarObjects_.end() );
99
100        // Create everything needed to display the object on the radar and add it to the map
101        Ogre::PanelOverlayElement* panel;
102        panel = static_cast<Ogre::PanelOverlayElement*>(
103            Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "RadarDot" + getUniqueNumberString()));
104        this->overlay_->add2D(panel);
105        // get right material
106        panel->setMaterialName(TextureGenerator::getMaterialName(
107            shapeMaterials_[object->getRadarObjectShape()], object->getRadarObjectColour()));
108        this->radarObjects_[object] = panel;
109    }
110
111    void HUDRadar::removeObject(RadarViewable* object)
112    {
113        // If object was added at all then remove it
114        std::map<RadarViewable*,Ogre::PanelOverlayElement*>::iterator it;
115        it = this->radarObjects_.find( object );
116        if( it != this->radarObjects_.end() )
117        {
118            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second);
119            this->radarObjects_.erase(it);
120        }
121    }
122
123    void HUDRadar::objectChanged( RadarViewable* rv )
124    {
125        if (rv == dynamic_cast<RadarViewable*>(this->owner_))
126            return;
127        assert( this->radarObjects_.find(rv) != this->radarObjects_.end() );
128        Ogre::PanelOverlayElement* panel = this->radarObjects_[rv];
129        panel->setMaterialName(TextureGenerator::getMaterialName(
130            shapeMaterials_[rv->getRadarObjectShape()], rv->getRadarObjectColour()));
131    }
132
133    void HUDRadar::gatherObjects()
134    {
135        const std::set<RadarViewable*>& objectSet = this->getCreator()->getScene()->getRadar()->getRadarObjects();
136        std::set<RadarViewable*>::const_iterator it;
137        for( it=objectSet.begin(); it!=objectSet.end(); ++it )
138            this->addObject(*it);
139    }
140
141    void HUDRadar::radarTick(float dt)
142    {
143        // Make sure the owner of the radar was defined
144        if( !this->owner_ )
145            return;
146
147        this->marker_->hide();      // in case that no object is in focus
148        // get the focus object
149        Radar* radar = this->getOwner()->getScene()->getRadar();
150        const RadarViewable* focusObject = radar->getFocus();
151
152        // update the distances for all objects
153        std::map<RadarViewable*,Ogre::PanelOverlayElement*>::iterator it;
154        for( it = this->radarObjects_.begin(); it != this->radarObjects_.end(); ++it )
155        {
156            // Make sure the object really is a WorldEntity
157            const WorldEntity* wePointer = it->first->getWorldEntity();
158            if( !wePointer )
159            {
160                CCOUT(0) << "Cannot display a non-WorldEntitiy on the radar" << std::endl;
161                assert(0);
162            }
163            bool isFocus = (it->first == focusObject);
164            // set size to fit distance...
165            float distance = (wePointer->getWorldPosition() - this->owner_->getPosition()).length();
166            // calculate the size with 1/distance dependency for simplicity (instead of exp(-distance * lambda)
167            float size = maximumDotSize_ * halfDotSizeDistance_ / (halfDotSizeDistance_ + distance);
168            it->second->setDimensions(size, size);
169
170            // calc position on radar...
171            Vector2 coord = get2DViewcoordinates(this->owner_->getPosition(), this->owner_->getOrientation() * WorldEntity::FRONT, this->owner_->getOrientation() * WorldEntity::UP, wePointer->getWorldPosition());
172            coord *= math::pi / 3.5f; // small adjustment to make it fit the texture
173            it->second->setPosition((1.0f + coord.x - size) * 0.5f, (1.0f - coord.y - size) * 0.5f);
174            it->second->show();
175
176            // if this object is in focus, then set the focus marker
177            if (isFocus)
178            {
179                this->marker_->setDimensions(size * 1.5f, size * 1.5f);
180                this->marker_->setPosition((1.0f + coord.x - size * 1.5f) * 0.5f, (1.0f - coord.y - size * 1.5f) * 0.5f);
181                this->marker_->show();
182            }
183        }
184    }
185
186    void HUDRadar::changedOwner()
187    {
188        SUPER(HUDRadar, changedOwner);
189
190        this->owner_ = orxonox_cast<ControllableEntity*>(this->getOwner());
191        assert(this->radarObjects_.size() == 0);
192        this->gatherObjects();
193    }
194}
Note: See TracBrowser for help on using the repository browser.