Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/hud/src/orxonox/overlays/OrxonoxOverlay.cc @ 1618

Last change on this file since 1618 was 1618, checked in by rgrieder, 16 years ago
  • moved colours of the SpeedBar to XML file
  • enabled render window updating in inactive mode (under windows the render window didn't show anything if inactive)
  • added row/column to ticpp error description (there are a lot more to do this, may modify the macro..)
  • Property svn:eol-style set to native
File size: 8.4 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 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "OrxonoxOverlay.h"
31
32#include <cmath>
33#include <OgreOverlayManager.h>
34#include <OgrePanelOverlayElement.h>
35#include "util/Convert.h"
36#include "util/String.h"
37#include "core/CoreIncludes.h"
38#include "core/XMLPort.h"
39#include "core/ConsoleCommand.h"
40#include "GraphicsEngine.h"
41
42namespace orxonox
43{
44    unsigned int OrxonoxOverlay::hudOverlayCounter_s = 0;
45    std::map<std::string, OrxonoxOverlay*> OrxonoxOverlay::overlays_s;
46
47    SetConsoleCommand(OrxonoxOverlay, scaleOverlay, false).setAccessLevel(AccessLevel::User);
48    SetConsoleCommand(OrxonoxOverlay, scrollOverlay, false).setAccessLevel(AccessLevel::User);
49    SetConsoleCommand(OrxonoxOverlay, rotateOverlay, false).setAccessLevel(AccessLevel::User);
50
51    OrxonoxOverlay::OrxonoxOverlay()
52        : overlay_(0)
53        , background_(0)
54        , windowAspectRatio_(1.0f)
55        , bCorrectAspect_(false)
56        , size_(1.0f, 1.0f)
57        , sizeCorrection_(1.0f, 1.0f)
58        , angle_(0.0f)
59        , position_(0.0f, 0.0f)
60        , origin_(0.0f, 0.0f)
61    {
62        RegisterObject(OrxonoxOverlay);
63    }
64
65    OrxonoxOverlay::~OrxonoxOverlay()
66    {
67        if (this->background_)
68            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->background_);
69
70        std::map<std::string, OrxonoxOverlay*>::iterator it = overlays_s.find(this->getName());
71        if (it != overlays_s.end())
72            overlays_s.erase(it);
73    }
74
75    void OrxonoxOverlay::XMLPort(Element& xmlElement, XMLPort::Mode mode)
76    {
77        BaseObject::XMLPort(xmlElement, mode);
78
79        if (mode == XMLPort::LoadObject)
80        {
81            if (overlays_s.find(this->getName()) != overlays_s.end())
82            {
83                COUT(1) << "Overlay names should be unique or you cannnot access them via console." << std::endl;
84            }
85            overlays_s[this->getName()] = this;
86
87            overlay_ = Ogre::OverlayManager::getSingleton().create("OrxonoxOverlay_overlay_"
88                + convertToString(hudOverlayCounter_s++));
89
90            // create background
91            this->background_ = static_cast<Ogre::PanelOverlayElement*>(
92                Ogre::OverlayManager::getSingleton().createOverlayElement("Panel",
93                "OrxonoxOverlay_background_" + convertToString(hudOverlayCounter_s++)));
94            this->overlay_->add2D(this->background_);
95
96            this->windowResized(GraphicsEngine::getSingleton().getWindowWidth(),
97                GraphicsEngine::getSingleton().getWindowHeight());
98        }
99
100        XMLPortParam(OrxonoxOverlay, "correctAspect", setAspectCorrection, getAspectCorrection, xmlElement, mode);
101        XMLPortParam(OrxonoxOverlay, "size", setSize, getUncorrectedSize, xmlElement, mode);
102        XMLPortParam(OrxonoxOverlay, "rotation", setRotation, getRotation, xmlElement, mode);
103        XMLPortParam(OrxonoxOverlay, "origin", setOrigin, getOrigin, xmlElement, mode);
104        XMLPortParam(OrxonoxOverlay, "position", setPosition, getPosition, xmlElement, mode);
105        XMLPortParam(OrxonoxOverlay, "background", setBackgroundMaterial, getBackgroundMaterial, xmlElement, mode);
106
107        if (mode == XMLPort::LoadObject)
108        {
109            this->overlay_->show();
110            if (!this->isVisible())
111                this->overlay_->hide();
112
113            this->sizeCorrectionChanged();
114            this->sizeChanged();
115            this->positionChanged();
116            this->angleChanged();
117        }
118    }
119
120    void OrxonoxOverlay::setBackgroundMaterial(const std::string& material)
121    {
122        if (this->background_ && material != "")
123            this->background_->setMaterialName(material);
124    }
125
126    const std::string& OrxonoxOverlay::getBackgroundMaterial() const
127    {
128        if (this->background_)
129            return this->background_->getMaterialName();
130        else
131            return blankString;
132    }
133
134    void OrxonoxOverlay::changedVisibility()
135    {
136        if (this->overlay_)
137        {
138            if (this->isVisible())
139                this->overlay_->show();
140            else
141                this->overlay_->hide();
142        }
143    }
144
145    void OrxonoxOverlay::windowResized(int newWidth, int newHeight)
146    {
147        this->windowAspectRatio_ = newWidth/(float)newHeight;
148
149        this->setAspectCorrection(this->bCorrectAspect_);
150    }
151
152    void OrxonoxOverlay::setAspectCorrection(bool val)
153    {
154        this->bCorrectAspect_ = val;
155        this->sizeCorrectionChanged();
156    }
157
158    void OrxonoxOverlay::sizeCorrectionChanged()
159    {
160        if (this->bCorrectAspect_)
161        {
162            float angle = this->angle_.valueDegrees();
163            if (angle < 0.0)
164                angle = -angle;
165            angle -= 180.0 * (int)(angle / 180.0);
166
167            float tempAspect;
168            if (angle > 89.0 && angle < 91.0)
169                tempAspect = 1.0 / this->windowAspectRatio_;
170            else if (angle > 179 || angle < 1)
171                tempAspect = this->windowAspectRatio_;
172            else
173                tempAspect = 1.0;
174
175            // note: this is only an approximation that is mostly valid when the
176            // magnitude of the width is about the magnitude of the height.
177            // Correctly we would have to take the square root of width*height
178            this->sizeCorrection_.x = 2.0 / (tempAspect + 1.0);
179            this->sizeCorrection_.y = tempAspect * this->sizeCorrection_.x;
180        }
181        else
182        {
183            this->sizeCorrection_ = Vector2::UNIT_SCALE;
184        }
185        this->sizeChanged();
186    }
187
188    /**
189    @remarks
190        This function can be overriden by any derivative.
191    */
192    void OrxonoxOverlay::sizeChanged()
193    {
194        this->overlay_->setScale(size_.x * sizeCorrection_.x, size_.y * sizeCorrection_.y);
195        positionChanged();
196    }
197
198    /**
199    @remarks
200        This function can be overriden by any derivative.
201    */
202    void OrxonoxOverlay::angleChanged()
203    {
204        this->overlay_->setRotate(this->angle_);
205        this->sizeCorrectionChanged();
206    }
207
208    /**
209    @remarks
210        This function can be overriden by any derivative.
211    */
212    void OrxonoxOverlay::positionChanged()
213    {
214        float angle = this->angle_.valueRadians();
215        if (angle < 0.0)
216            angle = -angle;
217        angle -= Ogre::Math::PI * (int)(angle / (Ogre::Math::PI));
218        if (angle > Ogre::Math::PI * 0.5)
219            angle = Ogre::Math::PI - angle;
220        Vector2 actualSize = size_ * sizeCorrection_;
221        float radius = actualSize.length();
222        float phi = atan(actualSize.y / actualSize.x);
223        Vector2 boundingBox(radius * cos(angle - phi), radius * sin(angle + phi));
224        Vector2 scroll = (position_ - 0.5 - boundingBox * (origin_ - 0.5)) * 2.0;
225        this->overlay_->setScroll(scroll.x, -scroll.y);
226    }
227
228
229    /*static*/ void OrxonoxOverlay::scaleOverlay(const std::string& name, float scale)
230    {
231        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
232        if (it != overlays_s.end())
233            (*it).second->scale(Vector2(scale, scale));
234    }
235
236    /*static*/ void OrxonoxOverlay::scrollOverlay(const std::string& name, const Vector2& scroll)
237    {
238        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
239        if (it != overlays_s.end())
240            (*it).second->scroll(scroll);
241    }
242
243    /*static*/ void OrxonoxOverlay::rotateOverlay(const std::string& name, const Degree& angle)
244    {
245        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
246        if (it != overlays_s.end())
247            (*it).second->rotate(angle);
248    }
249}
Note: See TracBrowser for help on using the repository browser.