Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 12384 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
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 *      David 'davidsa' Salvisberg
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
36#include "core/CoreIncludes.h"
37#include "core/XMLPort.h"
38#include "graphics/Billboard.h"
39#include "CameraManager.h"
40#include "Camera.h"
41#include "RenderQueueListener.h"
42#include "Scene.h"
43
44#include <OgreSphere.h>
45#include <OgreRenderWindow.h>
46#include <OgreCamera.h>
47
48namespace orxonox
49{
50    RegisterClass(LensFlare);
51   
52    LensFlare::LensFlare(Context* context) : StaticEntity(context), scale_(1.0f), fadeOnViewBorder_(true), fadeResolution_(7), fadeExponent_(2.0f)
53    {
54        RegisterObject(LensFlare);
55       
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);
65       
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);
78        XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f);
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);
82        XMLPortParam(LensFlare, "colour", setColour, getColour, xmlelement, mode);
83    }
84   
85    void LensFlare::registerVariables()
86    {
87        registerVariable(this->scale_, VariableDirection::ToClient);
88        registerVariable(this->fadeOnViewBorder_, VariableDirection::ToClient);
89        registerVariable(this->fadeResolution_, VariableDirection::ToClient);
90    }
91
92    /**
93    @brief
94        This function creates all the billboards needed for the flare effect
95    */
96    void LensFlare::createBillboards()
97    {
98        this->occlusionBillboard_ = new Billboard(this->getContext());
99        this->occlusionBillboard_->setMaterial("lensflare/hoq");
100        this->occlusionBillboard_->setVisible(false);
101        this->occlusionBillboard_->disableFrustumCulling();
102        this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ);
103        this->attach(this->occlusionBillboard_);
104       
105        for (const LensFlare::Lens& lens : lensConfiguration_)
106        {
107            Billboard* lensPart = new Billboard(this->getContext());
108            lensPart->setMaterial(lens.material_);
109            lensPart->disableFrustumCulling();
110            lensPart->setVisible(true);
111            this->attach(lensPart);
112            this->billboards_.push_back(lensPart);
113        }
114    }
115
116    /**
117    @brief
118        This function updates the states of all the billboards, i.e. their positions, visibilty and dimensions
119    @param viewDirection
120        normalised vector pointing from the current camera to the point light center
121    @param dimension
122        the current dimension of the main billboard, we're always using square billboards
123    @param lightIsVisible
124        is the (point-)light source currently visible
125    */
126    void LensFlare::updateBillboardStates(const Vector3& viewDirection, float dimension, bool lightIsVisible)
127    { 
128        this->occlusionBillboard_->setDefaultDimensions(dimension * 0.5f, dimension * 0.5f);
129        this->occlusionBillboard_->setVisible(lightIsVisible);
130
131        int i = 0;
132        for (Billboard* billboard : this->billboards_)
133        {
134            const LensFlare::Lens& lens = lensConfiguration_.at(i);
135            billboard->setPosition(-viewDirection * (1.0f - lens.position_));
136            billboard->setVisible(lightIsVisible);
137            billboard->setDefaultDimensions(dimension * lens.scale_, dimension * lens.scale_);
138            i++;
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    {
150        ColourValue cur = this->colour_;
151
152        int i = 0;
153        for (Billboard* billboard : this->billboards_)
154        {
155            cur.a = alpha * lensConfiguration_.at(i).alpha_;
156            billboard->setColour(cur);
157            i++;
158        }
159    }
160   
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    */
169    unsigned int LensFlare::getPointCount(float dimension) const
170    {
171        Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera();
172        Vector3 position = this->getWorldPosition();
173        Vector3 nX = camera->getDerivedOrientation().xAxis().normalisedCopy();
174        Vector3 nY = camera->getDerivedOrientation().yAxis().normalisedCopy();
175        int halfRes = fadeResolution_ / 2;
176        float resDim = dimension / fadeResolution_;
177        unsigned int count = 0;
178        for (int i = -halfRes; i <= halfRes; i++)
179        {
180            for (int j = -halfRes; j <= halfRes; j++)
181            {
182                Vector3 point = position + (i*resDim) * nX + (j*resDim) * nY;//generate point samples
183                if (camera->isVisible(point))
184                {
185                    count++;
186                }
187            }
188        }
189        return count;
190    }
191
192    void LensFlare::tick(float dt)
193    {
194        if(this->isVisible())
195        {
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_)
201            {
202                this->fadeResolution_ = 3;//this is so we can still determine when the billboard has left the screen
203            }
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_);
210                float left, right, top, bottom;
211                camera->projectSphere(sphere, &left, &top, &right, &bottom);//approximate maximum pixel count of billboard with a sphere
212               
213                Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
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_)
219                {
220                    borderRatio = ((float) pointCount) / (((float) fadeResolution_) * ((float) fadeResolution_));//ratio for the border fade
221                }
222                //update alpha values of all billboards except the HOQ billboard
223                this->updateBillboardAlphas(std::min(1.0f, std::pow(std::min(ratio, borderRatio), this->fadeExponent_)));
224            }
225        }
226    }
227
228    void LensFlare::changedVisibility()
229    {
230     
231    }
232}
Note: See TracBrowser for help on using the repository browser.