Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc @ 8351

Last change on this file since 8351 was 8351, checked in by rgrieder, 13 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

  • No support for CEGUI 0.5, Ogre 1.4 and boost 1.35 - 1.39 any more
  • In game console is not working in main menu for CEGUI 0.7
  • Tolua (just the C lib, not the application) and CEGUILua libraries are no longer in our repository. —> You will need to get these as well when compiling Orxonox
  • And of course lots of new bugs we don't yet know about
  • Property svn:eol-style set to native
File size: 13.8 KB
RevLine 
[1588]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
[1622]29/**
30@file
31@brief Definition of the OrxonoxOverlay class.
32*/
33
[1601]34#include "OrxonoxOverlay.h"
[1588]35
[1615]36#include <cmath>
[1622]37#include <OgreOverlay.h>
[1588]38#include <OgreOverlayManager.h>
[1614]39#include <OgrePanelOverlayElement.h>
[2896]40#include <OgreRenderWindow.h>
[6417]41#include <OgreMaterialManager.h>
42#include <OgreTechnique.h>
43#include <OgrePass.h>
[2896]44
[1588]45#include "util/Convert.h"
[2171]46#include "util/Exception.h"
[2896]47#include "core/GameMode.h"
[1588]48#include "core/CoreIncludes.h"
[1616]49#include "core/XMLPort.h"
[7284]50#include "core/command/ConsoleCommand.h"
[1588]51
[5980]52#include "OverlayGroup.h"
53
[1588]54namespace orxonox
55{
[1615]56    unsigned int OrxonoxOverlay::hudOverlayCounter_s = 0;
57    std::map<std::string, OrxonoxOverlay*> OrxonoxOverlay::overlays_s;
[1588]58
[7284]59    SetConsoleCommand("OrxonoxOverlay", "scaleOverlay",     &OrxonoxOverlay::scaleOverlay);
60    SetConsoleCommand("OrxonoxOverlay", "scrollOverlay",    &OrxonoxOverlay::scrollOverlay);
61    SetConsoleCommand("OrxonoxOverlay", "toggleVisibility", &OrxonoxOverlay::toggleVisibility);
[8309]62    SetConsoleCommand("OrxonoxOverlay", "show",     &OrxonoxOverlay::showOverlay);
[7284]63    SetConsoleCommand("OrxonoxOverlay", "rotateOverlay",    &OrxonoxOverlay::rotateOverlay);
[1588]64
[2087]65    OrxonoxOverlay::OrxonoxOverlay(BaseObject* creator)
66        : BaseObject(creator)
[1615]67    {
68        RegisterObject(OrxonoxOverlay);
[2087]69
[2662]70        this->owner_ = 0;
71        this->group_ = 0;
72
[2896]73        if (!GameMode::showsGraphics())
[2171]74            ThrowException(NoGraphics, "Can't create OrxonoxOverlay, graphics engine not initialized");
75
[2087]76        // create the Ogre::Overlay
77        overlay_ = Ogre::OverlayManager::getSingleton().create("OrxonoxOverlay_overlay_"
[3280]78            + multi_cast<std::string>(hudOverlayCounter_s++));
[2087]79
80        // create background panel (can be used to show any picture)
81        this->background_ = static_cast<Ogre::PanelOverlayElement*>(
82            Ogre::OverlayManager::getSingleton().createOverlayElement("Panel",
[3280]83            "OrxonoxOverlay_background_" + multi_cast<std::string>(hudOverlayCounter_s++)));
[2087]84        this->overlay_->add2D(this->background_);
85
[2896]86        // Get aspect ratio from the render window. Later on, we get informed automatically
[3327]87        this->windowAspectRatio_ = static_cast<float>(this->getWindowWidth()) / this->getWindowHeight();
[2087]88
[6417]89        this->size_ = Vector2(1.0f, 1.0f);
90        this->pickPoint_= Vector2(0.0f, 0.0f);
91        this->position_ = Vector2(0.0f, 0.0f);
92        this->angle_ = Degree(0.0);
93        this->bCorrectAspect_ = false;
94        this->rotState_ = Horizontal;
95        this->angleChanged(); // updates all other values as well
[2087]96
97        setBackgroundMaterial("");
[1615]98    }
[1614]99
[1622]100    /**
101    @brief
102        Make sure everything gets removed/destroyed.
103    @remark
104        We assume that the Ogre::OverlayManager exists (there is an assert in Ogre for that!)
105    */
[1615]106    OrxonoxOverlay::~OrxonoxOverlay()
107    {
[2087]108        if (this->isInitialized())
109        {
110            // erase ourself from the map with all overlays
111            std::map<std::string, OrxonoxOverlay*>::iterator it = overlays_s.find(this->getName());
112            if (it != overlays_s.end())
113                overlays_s.erase(it);
[1622]114
115            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->background_);
116            Ogre::OverlayManager::getSingleton().destroy(this->overlay_);
[2087]117        }
[1615]118    }
119
[1622]120    /**
121    @brief
122        Loads the OrxonoxOverlay.
[1747]123
[1622]124        This has to be called before usage, otherwise strange behaviour is
125        guaranteed! (there should be no segfaults however).
126    @copydoc
127        BaseObject::XMLPort()
128    */
[7401]129    void OrxonoxOverlay::XMLPort(Element& xmlelement, XMLPort::Mode mode)
[1590]130    {
[7401]131        SUPER(OrxonoxOverlay, XMLPort, xmlelement, mode);
[1588]132
[7401]133        XMLPortParam(OrxonoxOverlay, "size",      setSize,      getSize,      xmlelement, mode);
134        XMLPortParam(OrxonoxOverlay, "pickpoint", setPickPoint, getPickPoint, xmlelement, mode);
135        XMLPortParam(OrxonoxOverlay, "position",  setPosition,  getPosition,  xmlelement, mode);
136        XMLPortParam(OrxonoxOverlay, "rotation",  setRotation,  getRotation,  xmlelement, mode);
137        XMLPortParam(OrxonoxOverlay, "correctaspect", setAspectCorrection,   getAspectCorrection,   xmlelement, mode);
138        XMLPortParam(OrxonoxOverlay, "background",    setBackgroundMaterial, getBackgroundMaterial, xmlelement, mode);
[2087]139    }
[1614]140
[2087]141    void OrxonoxOverlay::changedName()
142    {
[2662]143        SUPER(OrxonoxOverlay, changedName);
144
[2087]145        OrxonoxOverlay::overlays_s.erase(this->getOldName());
[1590]146
[2087]147        if (OrxonoxOverlay::overlays_s.find(this->getName()) != OrxonoxOverlay::overlays_s.end())
[6417]148            COUT(1) << "Overlay names should be unique or you cannnot access them via console. Name: \"" << this->getName() << '"' << std::endl;
[1588]149
[2087]150        OrxonoxOverlay::overlays_s[this->getName()] = this;
[1590]151    }
[1588]152
[1622]153    //! Only sets the background material name if not ""
[1615]154    void OrxonoxOverlay::setBackgroundMaterial(const std::string& material)
155    {
[6417]156        if (this->background_ && !material.empty())
[1615]157            this->background_->setMaterialName(material);
158    }
[1588]159
[1622]160    //! Returns the the material name of the background
[1615]161    const std::string& OrxonoxOverlay::getBackgroundMaterial() const
162    {
163        if (this->background_)
164            return this->background_->getMaterialName();
165        else
[2087]166            return BLANKSTRING;
[1615]167    }
[1614]168
[1622]169    //! Called by BaseObject when visibility has changed.
[1615]170    void OrxonoxOverlay::changedVisibility()
[1595]171    {
[5980]172        SUPER( OrxonoxOverlay, changedVisibility );
[6417]173
[1622]174        if (!this->overlay_)
175            return;
176
[5980]177        // only set to visible if corresponding OverlayGroup is also visible
178        if (this->isVisible() && (!this->getOverlayGroup() || this->getOverlayGroup()->isVisible()) )
[1622]179            this->overlay_->show();
180        else
181            this->overlay_->hide();
[1595]182    }
[1588]183
[1622]184    /**
185    @brief
[2896]186        Called by the GraphicsManager whenever the window size changes.
[1622]187        Calculates the aspect ratio only.
188    */
[2896]189    void OrxonoxOverlay::windowResized(unsigned int newWidth, unsigned int newHeight)
[1615]190    {
[3301]191        this->windowAspectRatio_ = static_cast<float>(newWidth) / newHeight;
[1622]192        this->sizeCorrectionChanged();
[1615]193    }
[1590]194
[1622]195    /**
196    @brief
197        Called whenever the rotation angle has changed.
198    */
199    void OrxonoxOverlay::angleChanged()
[1595]200    {
[1622]201        if (!this->overlay_)
202            return;
203
204        this->overlay_->setRotate(this->angle_);
[1615]205        this->sizeCorrectionChanged();
[1595]206    }
[1615]207
[1622]208    /**
209    @brief
210        Called whenever the aspect ratio or the angle has changed.
211        The method calculates a correction factor for the size to compensate
212        for aspect distortion if desired.
213    @remarks
214        This only works when the angle is about 0 or 90 degrees.
215    */
[1615]216    void OrxonoxOverlay::sizeCorrectionChanged()
[1595]217    {
[1615]218        if (this->bCorrectAspect_)
219        {
220            float angle = this->angle_.valueDegrees();
[1618]221            if (angle < 0.0)
222                angle = -angle;
[3301]223            angle -= 180.0f * static_cast<int>(angle / 180.0);
[1618]224
[1622]225            // take the reverse if angle is about 90 degrees
[1615]226            float tempAspect;
[3196]227            if (angle > 89.0f && angle < 91.0f)
[1632]228            {
[6502]229                tempAspect = 1.0f / this->windowAspectRatio_;
[1632]230                rotState_ = Vertical;
231            }
[1618]232            else if (angle > 179 || angle < 1)
[1632]233            {
[1615]234                tempAspect = this->windowAspectRatio_;
[1632]235                rotState_ = Horizontal;
236            }
[1615]237            else
[1632]238            {
[3196]239                tempAspect = 1.0f;
[1632]240                rotState_ = Inbetween;
241            }
[1615]242
243            // note: this is only an approximation that is mostly valid when the
244            // magnitude of the width is about the magnitude of the height.
245            // Correctly we would have to take the square root of width*height
[3196]246            this->sizeCorrection_.x = 2.0f / (tempAspect + 1.0f);
[1615]247            this->sizeCorrection_.y = tempAspect * this->sizeCorrection_.x;
248        }
249        else
250        {
251            this->sizeCorrection_ = Vector2::UNIT_SCALE;
252        }
[1622]253
[1615]254        this->sizeChanged();
[1595]255    }
256
[1615]257    /**
[1622]258    @brief
259        Sets the overlay size using the actual corrected size.
[1615]260    */
261    void OrxonoxOverlay::sizeChanged()
262    {
[1622]263        if (!this->overlay_)
264            return;
265
[1615]266        this->overlay_->setScale(size_.x * sizeCorrection_.x, size_.y * sizeCorrection_.y);
267        positionChanged();
268    }
[1595]269
[1615]270    /**
[1622]271    @brief
272        Determines the position of the overlay.
273        This works also well when a rotation angle is applied. The overlay always
274        gets aligned correctly as well as possible.
[1615]275    */
[1622]276    void OrxonoxOverlay::positionChanged()
[1615]277    {
[1622]278        if (!this->overlay_)
279            return;
[1595]280
[1622]281        // transform the angle to a range of 0 - pi/2 first.
[1617]282        float angle = this->angle_.valueRadians();
283        if (angle < 0.0)
284            angle = -angle;
[7184]285        angle -= math::pi * static_cast<int>(angle / (math::pi));
[8351]286        if (angle > math::pi_2)
[7184]287            angle = math::pi - angle;
[1747]288
[1622]289        // do some mathematical fiddling for a bounding box
[1615]290        Vector2 actualSize = size_ * sizeCorrection_;
291        float radius = actualSize.length();
292        float phi = atan(actualSize.y / actualSize.x);
293        Vector2 boundingBox(radius * cos(angle - phi), radius * sin(angle + phi));
[1622]294
295        // calculate the scrolling offset
296        Vector2 scroll = (position_ - 0.5 - boundingBox * (pickPoint_ - 0.5)) * 2.0;
[1615]297        this->overlay_->setScroll(scroll.x, -scroll.y);
298    }
[1598]299
[1615]300
[1622]301    //########### Console commands ############
302
303    /**
304    @brief
305        Scales an overlay by its name.
306    @param name
307        The name of the overlay defined BaseObject::setName() (usually done with the "name"
[1623]308        attribute in the xml file).
[7401]309    @param scale
310        The scaling factor
[1622]311    */
[1615]312    /*static*/ void OrxonoxOverlay::scaleOverlay(const std::string& name, float scale)
313    {
314        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
315        if (it != overlays_s.end())
[6417]316            it->second->scale(Vector2(scale, scale));
[1615]317    }
318
[1622]319    /**
320    @brief
[2993]321        Toggles the visibility of an Overlay by it's name.
322    @param name
323        The name of the overlay defined BaseObject::setName() (usually done with the "name"
324        attribute in the xml file).
325    */
326    /*static*/ void OrxonoxOverlay::toggleVisibility(const std::string& name)
327    {
328        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
329        if (it != overlays_s.end())
330        {
[6417]331            OrxonoxOverlay* overlay= it->second;
[2993]332            if(overlay->isVisible())
[6711]333            {
[2993]334                overlay->hide();
[6799]335                COUT(4) << "HIDE " << name << std::endl;
[6711]336            }
[2993]337            else
[6711]338            {
[2993]339                overlay->show();
[6799]340                COUT(4) << "SHOW " << name << std::endl;
[6711]341            }
[2993]342        }
343    }
[8309]344   
345    /**
346    @brief
347        Shows Overlay by it's name.
348    @param name
349        The name of the overlay defined BaseObject::setName() (usually done with the "name"
350        attribute in the xml file).
351    */
352    /*static*/ void OrxonoxOverlay::showOverlay(const std::string& name)
353    {
354        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
355        if (it != overlays_s.end())
356        {
357            OrxonoxOverlay* overlay= it->second;
358            if(overlay->isVisible())
359                overlay->changedVisibility();
360            else
361                overlay->show();
362        }
363    }
[2993]364
365    /**
366    @brief
[1622]367        Scrolls an overlay by its name.
368    @param name
369        The name of the overlay defined BaseObject::setName() (usually done with the "name"
[1623]370        attribute in the xml file).
[7401]371    @param scroll
372        The relative translation of the overlay
[1622]373    */
[1615]374    /*static*/ void OrxonoxOverlay::scrollOverlay(const std::string& name, const Vector2& scroll)
375    {
376        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
377        if (it != overlays_s.end())
[6417]378            it->second->scroll(scroll);
[1615]379    }
380
[1622]381    /**
382    @brief
383        Rotates an overlay by its name.
384    @param name
385        The name of the overlay defined BaseObject::setName() (usually done with the "name"
[1623]386        attribute in the xml file).
[7401]387    @param angle
388        The rotation angle in degree
[1622]389    */
[1615]390    /*static*/ void OrxonoxOverlay::rotateOverlay(const std::string& name, const Degree& angle)
391    {
392        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
393        if (it != overlays_s.end())
[6417]394            it->second->rotate(angle);
[1615]395    }
[6057]396
397    void OrxonoxOverlay::setOverlayGroup(OverlayGroup* group)
398    {
399        if (group != this->group_)
400        {
401            if (this->group_)
402                this->group_->removeElement(this);
403            this->group_ = group;
404            this->changedOverlayGroup();
405        }
406    }
[6417]407
408    void OrxonoxOverlay::setBackgroundAlpha(float alpha) {
409        Ogre::MaterialPtr ptr = this->background_->getMaterial();
410        Ogre::TextureUnitState* tempTx = ptr->getTechnique(0)->getPass(0)->getTextureUnitState(0);
411        tempTx->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, alpha);
412    }
[1588]413}
Note: See TracBrowser for help on using the repository browser.