Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1617 was 1617, checked in by rgrieder, 16 years ago
  • some more fixes..
  • Property svn:eol-style set to native
File size: 8.3 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->sizeChanged();
114            this->positionChanged();
115            this->angleChanged();
116        }
117    }
118
119    void OrxonoxOverlay::setBackgroundMaterial(const std::string& material)
120    {
121        if (this->background_ && material != "")
122            this->background_->setMaterialName(material);
123    }
124
125    const std::string& OrxonoxOverlay::getBackgroundMaterial() const
126    {
127        if (this->background_)
128            return this->background_->getMaterialName();
129        else
130            return blankString;
131    }
132
133    void OrxonoxOverlay::changedVisibility()
134    {
135        if (this->overlay_)
136        {
137            if (this->isVisible())
138                this->overlay_->show();
139            else
140                this->overlay_->hide();
141        }
142    }
143
144    void OrxonoxOverlay::windowResized(int newWidth, int newHeight)
145    {
146        this->windowAspectRatio_ = newWidth/(float)newHeight;
147
148        this->setAspectCorrection(this->bCorrectAspect_);
149    }
150
151    void OrxonoxOverlay::setAspectCorrection(bool val)
152    {
153        this->bCorrectAspect_ = val;
154        this->sizeCorrectionChanged();
155    }
156
157    void OrxonoxOverlay::sizeCorrectionChanged()
158    {
159        if (this->bCorrectAspect_)
160        {
161            float angle = this->angle_.valueDegrees();
162            float tempAspect;
163            if (angle > 89.0 && angle < 91.0 || angle > 269 && angle < 271)
164                tempAspect = 1.0 / this->windowAspectRatio_;
165            else if (angle > 359 && angle < 1 || angle > 179 && angle < 181)
166                tempAspect = this->windowAspectRatio_;
167            else
168                tempAspect = 1.0;
169
170            // note: this is only an approximation that is mostly valid when the
171            // magnitude of the width is about the magnitude of the height.
172            // Correctly we would have to take the square root of width*height
173            this->sizeCorrection_.x = 2.0 / (tempAspect + 1.0);
174            this->sizeCorrection_.y = tempAspect * this->sizeCorrection_.x;
175        }
176        else
177        {
178            this->sizeCorrection_ = Vector2::UNIT_SCALE;
179        }
180        this->sizeChanged();
181    }
182
183    /**
184    @remarks
185        This function can be overriden by any derivative.
186    */
187    void OrxonoxOverlay::sizeChanged()
188    {
189        this->overlay_->setScale(size_.x * sizeCorrection_.x, size_.y * sizeCorrection_.y);
190        positionChanged();
191    }
192
193    /**
194    @remarks
195        This function can be overriden by any derivative.
196    */
197    void OrxonoxOverlay::angleChanged()
198    {
199        this->overlay_->setRotate(this->angle_);
200        this->sizeCorrectionChanged();
201    }
202
203    /**
204    @remarks
205        This function can be overriden by any derivative.
206    */
207    void OrxonoxOverlay::positionChanged()
208    {
209        float angle = this->angle_.valueRadians();
210        if (angle < 0.0)
211            angle = -angle;
212        angle -= Ogre::Math::PI * (int)(angle / (Ogre::Math::PI));
213        if (angle > Ogre::Math::PI * 0.5)
214            angle = Ogre::Math::PI - angle;
215        Vector2 actualSize = size_ * sizeCorrection_;
216        float radius = actualSize.length();
217        float phi = atan(actualSize.y / actualSize.x);
218        Vector2 boundingBox(radius * cos(angle - phi), radius * sin(angle + phi));
219        Vector2 scroll = (position_ - 0.5 - boundingBox * (origin_ - 0.5)) * 2.0;
220        this->overlay_->setScroll(scroll.x, -scroll.y);
221    }
222
223
224    /*static*/ void OrxonoxOverlay::scaleOverlay(const std::string& name, float scale)
225    {
226        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
227        if (it != overlays_s.end())
228            (*it).second->scale(Vector2(scale, scale));
229    }
230
231    /*static*/ void OrxonoxOverlay::scrollOverlay(const std::string& name, const Vector2& scroll)
232    {
233        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
234        if (it != overlays_s.end())
235            (*it).second->scroll(scroll);
236    }
237
238    /*static*/ void OrxonoxOverlay::rotateOverlay(const std::string& name, const Degree& angle)
239    {
240        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
241        if (it != overlays_s.end())
242            (*it).second->rotate(angle);
243    }
244}
Note: See TracBrowser for help on using the repository browser.