Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/graphics/LensFlare.cc @ 11780

Last change on this file since 11780 was 11083, checked in by muemart, 9 years ago

Fix some clang-tidy warnings.
Also, Serialise.h was doing some C-style casts that ended up being const casts. I moved those const casts as close to the source as possible and changed the loadAndIncrease functions to not do that.

  • Property svn:eol-style set to native
File size: 9.6 KB
RevLine 
[9445]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:
[11075]23 *      David 'davidsa' Salvisberg
[9445]24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30  @file LensFlare.cc
31  @brief Implementation of the LensFlare class.
32*/
33
34#include "LensFlare.h"
35
[11083]36#include "core/CoreIncludes.h"
[9445]37#include "core/XMLPort.h"
38#include "graphics/Billboard.h"
39#include "CameraManager.h"
[11083]40#include "Camera.h"
[9448]41#include "RenderQueueListener.h"
[11083]42#include "Scene.h"
[9445]43
[9448]44#include <OgreSphere.h>
45#include <OgreRenderWindow.h>
[11083]46#include <OgreCamera.h>
[9448]47
[9445]48namespace orxonox
49{
[11073]50    RegisterClass(LensFlare);
[9445]51   
[11078]52    LensFlare::LensFlare(Context* context) : StaticEntity(context), scale_(1.0f), fadeOnViewBorder_(true), fadeResolution_(7), fadeExponent_(2.0f)
[9445]53    {
54        RegisterObject(LensFlare);
55       
[11078]56        this->lensConfiguration_.emplace_back("lensflare/burst",     1.0f,  1.0f, 1.0f); //main burst
57        this->lensConfiguration_.emplace_back("lensflare/burst",     0.7f,  1.2f, 1.05f); //secondary burst
58        this->lensConfiguration_.emplace_back("lensflare/bursthalo", 0.7f,  0.9f, 1.0f); //halo around main burst
59        this->lensConfiguration_.emplace_back("lensflare/ring",      0.1f,  2.5f, 0.9f); //all the different distanced lenses
60        this->lensConfiguration_.emplace_back("lensflare/iris",      0.1f,  0.2f, 0.5f);
61        this->lensConfiguration_.emplace_back("lensflare/halo5",     0.1f,  0.3f, 0.45f);
62        this->lensConfiguration_.emplace_back("lensflare/halo5",     0.4f,  0.2f, 0.35f);
63        this->lensConfiguration_.emplace_back("lensflare/iris",      0.1f,  0.4f, 0.25f);
64        this->lensConfiguration_.emplace_back("lensflare/halo4",     0.05f, 0.2f, 0.2f);
[9500]65       
[9445]66        this->createBillboards();
67       
68        this->registerVariables();
69    }
70
71    LensFlare::~LensFlare()
72    {
73    }
74
75    void LensFlare::XMLPort(Element& xmlelement, XMLPort::Mode mode)
76    {
77        SUPER(LensFlare, XMLPort, xmlelement, mode);
[9448]78        XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f);
[9461]79        XMLPortParam(LensFlare, "fadeOnViewBorder", setFadeOnViewBorder, isFadeOnViewBorder, xmlelement, mode).defaultValues(true);
80        XMLPortParam(LensFlare, "fadeResolution", setFadeResolution, getFadeResolution, xmlelement, mode).defaultValues(7);
81        XMLPortParam(LensFlare, "fadeExponent", setFadeExponent, getFadeExponent, xmlelement, mode).defaultValues(2.0f);
[9500]82        XMLPortParam(LensFlare, "colour", setColour, getColour, xmlelement, mode);
[9445]83    }
84   
85    void LensFlare::registerVariables()
86    {
[9461]87        registerVariable(this->scale_, VariableDirection::ToClient);
88        registerVariable(this->fadeOnViewBorder_, VariableDirection::ToClient);
89        registerVariable(this->fadeResolution_, VariableDirection::ToClient);
[9445]90    }
[9461]91
92    /**
93    @brief
94        This function creates all the billboards needed for the flare effect
95    */
[9445]96    void LensFlare::createBillboards()
97    {
[11073]98        this->occlusionBillboard_ = new Billboard(this->getContext());
[9448]99        this->occlusionBillboard_->setMaterial("lensflare/hoq");
100        this->occlusionBillboard_->setVisible(false);
[9461]101        this->occlusionBillboard_->disableFrustumCulling();
[9448]102        this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ);
103        this->attach(this->occlusionBillboard_);
104       
[11078]105        for (const LensFlare::Lens& lens : lensConfiguration_)
106        {
107            Billboard* lensPart = new Billboard(this->getContext());
108            lensPart->setMaterial(lens.material_);
[9500]109            lensPart->disableFrustumCulling();
110            lensPart->setVisible(true);
111            this->attach(lensPart);
[11079]112            this->billboards_.push_back(lensPart);
[9500]113        }
[9445]114    }
[9461]115
116    /**
117    @brief
118        This function updates the states of all the billboards, i.e. their positions, visibilty and dimensions
[9464]119    @param viewDirection
120        normalised vector pointing from the current camera to the point light center
[9461]121    @param dimension
122        the current dimension of the main billboard, we're always using square billboards
[9464]123    @param lightIsVisible
124        is the (point-)light source currently visible
[9461]125    */
[11078]126    void LensFlare::updateBillboardStates(const Vector3& viewDirection, float dimension, bool lightIsVisible)
[9461]127    { 
[11078]128        this->occlusionBillboard_->setDefaultDimensions(dimension * 0.5f, dimension * 0.5f);
[9500]129        this->occlusionBillboard_->setVisible(lightIsVisible);
[11078]130
131        int i = 0;
[11079]132        for (Billboard* billboard : this->billboards_)
[11078]133        {
134            const LensFlare::Lens& lens = lensConfiguration_.at(i);
135            billboard->setPosition(-viewDirection * (1.0f - lens.position_));
[9461]136            billboard->setVisible(lightIsVisible);
[11078]137            billboard->setDefaultDimensions(dimension * lens.scale_, dimension * lens.scale_);
[9464]138            i++;
[9461]139        }
140    }
141
142    /**
143    @brief
144        This function updates the alpha values for all billboards except for the one used for Hardware Occlusion Querying
145    @param alpha
146        the new alpha value all visible billboards should use
147    */
148    void LensFlare::updateBillboardAlphas(float alpha)
149    {
[11078]150        ColourValue cur = this->colour_;
151
152        int i = 0;
[11079]153        for (Billboard* billboard : this->billboards_)
[11078]154        {
155            cur.a = alpha * lensConfiguration_.at(i).alpha_;
156            billboard->setColour(cur);
[9466]157            i++;
[9461]158        }
159    }
[9445]160   
[9461]161    /**
162    @brief
163        This function generates point samples of the main burst billboard according to the fadeResolution and returns how many of them are in the view port
164    @param dimension
165        the current dimension of the main billboard, we're always using square billboards
166    @return
167        the absolute amount of point samples that are currently captured by the camera of the view port
168    */
[9466]169    unsigned int LensFlare::getPointCount(float dimension) const
[9445]170    {
[11078]171        Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera();
[9491]172        Vector3 position = this->getWorldPosition();
[9466]173        Vector3 nX = camera->getDerivedOrientation().xAxis().normalisedCopy();
174        Vector3 nY = camera->getDerivedOrientation().yAxis().normalisedCopy();
[11078]175        int halfRes = fadeResolution_ / 2;
176        float resDim = dimension / fadeResolution_;
177        unsigned int count = 0;
178        for (int i = -halfRes; i <= halfRes; i++)
[9461]179        {
[11078]180            for (int j = -halfRes; j <= halfRes; j++)
[9461]181            {
[11078]182                Vector3 point = position + (i*resDim) * nX + (j*resDim) * nY;//generate point samples
183                if (camera->isVisible(point))
[9461]184                {
185                    count++;
186                }
187            }
188        }
189        return count;
[9445]190    }
191
192    void LensFlare::tick(float dt)
193    {
194        if(this->isVisible())
195        {
[11078]196            // get the current distance of the lensflare center from the camera
197            Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
198            float cameraDistance = camera->getDerivedPosition().distance(this->getPosition());
199            float dimension = cameraDistance * this->scale_;
200            if (!this->fadeOnViewBorder_)
[9461]201            {
[11078]202                this->fadeResolution_ = 3;//this is so we can still determine when the billboard has left the screen
[9461]203            }
[11078]204            unsigned int pointCount = this->getPointCount(dimension * 0.25f * this->scale_);
205            Vector3 viewDirection = this->getWorldPosition() - camera->getDerivedPosition() - camera->getDerivedDirection() * cameraDistance;
206            this->updateBillboardStates(viewDirection, dimension, pointCount > 0);
207            if (pointCount > 0)
208            {
209                Ogre::Sphere sphere(this->getPosition(), dimension * 0.25f * this->scale_);
[9448]210                float left, right, top, bottom;
[11078]211                camera->projectSphere(sphere, &left, &top, &right, &bottom);//approximate maximum pixel count of billboard with a sphere
[9448]212               
213                Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
[11078]214                float maxCount = (right - left) * (top - bottom) * window->getWidth() * window->getHeight() * 0.25f;
215                unsigned int pixelCount = this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count
216                float ratio = (maxCount < 0.0f) ? 0.0f : (1.0f * pixelCount / maxCount);//prevent underflow and division by zero
217                float borderRatio = 1.0f;
218                if (this->fadeOnViewBorder_)
[9461]219                {
[11078]220                    borderRatio = ((float) pointCount) / (((float) fadeResolution_) * ((float) fadeResolution_));//ratio for the border fade
[9461]221                }
222                //update alpha values of all billboards except the HOQ billboard
[11078]223                this->updateBillboardAlphas(std::min(1.0f, std::pow(std::min(ratio, borderRatio), this->fadeExponent_)));
[9448]224            }
[9445]225        }
226    }
227
228    void LensFlare::changedVisibility()
229    {
[9461]230     
[9445]231    }
[11078]232}
Note: See TracBrowser for help on using the repository browser.