Project

General

Profile

SO3Engine
SO3DeferredLightPoint.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
26
27namespace SO3
28{
29
30SDeferredLightPoint::SDeferredLightPoint(Ogre::Light* originalLight, SDeferredLightMaterialGenerator* typeLightMaterialGenerator) : SDeferredLightImpl(originalLight, "Point", typeLightMaterialGenerator)
31{
32 radius = 0.0f;
33}
34
38
40{
41 // Original model
42 /*float outerRadius = ogreParentLight->getAttenuationRange();
43 float c = ogreParentLight->getAttenuationConstant();
44 float b = ogreParentLight->getAttenuationLinear();
45 float a = ogreParentLight->getAttenuationQuadric();
46
47 // Avoid a bad zero division
48 if (c != 1.0f || b != 0.0f || a != 0.0f)
49 {
50 // Calculate radius from Attenuation (dmax at wich attenuation factor is close to 0)
51 int threshold_level = 10;// difference of 10-15 levels deemed unnoticeable
52 float threshold = 1.0f/((float)threshold_level/256.0f);
53
54 // Use quadratic formula to determine outer radius
55 c = c-threshold;
56 float d=sqrt(b*b-4*a*c);
57 outerRadius = (-2*c)/(b+d);
58 outerRadius *= 1.2;
59 }
60 radius = outerRadius;*/
61
62 // Corrected Model
63 /*
64 // Calculate radius from Attenuation (dmax at wich attenuation factor is close to 0)
65 int threshold_level = 5;// difference of 10-15 levels deemed unnoticeable
66 float threshold = 1.0f/((float)threshold_level/256.0f);
67
68 float outerRadius = ogreParentLight->getAttenuationRange();
69 float c = ogreParentLight->getAttenuationConstant();
70 float b = ogreParentLight->getAttenuationLinear();
71 // minimum value for quadratic for make the formule works 0.01
72 float a = std::max<float>(ogreParentLight->getAttenuationQuadric(), 0.01);
73
74 // Use quadratic formula to determine outer radius
75 c = c-threshold;
76 float d=sqrt(b*b-4*a*c);
77 outerRadius = (-b + d) / (2*a);
78 radius = outerRadius * 1.2f;
79 */
80
81 radius = ogreParentLight->getAttenuationRange() * 1.5f;
82}
83
85{
86 //Ogre::Real newRadius = ogreParentLight->getAttenuationRange();
87 delete mRenderOp.vertexData;
88 delete mRenderOp.indexData;
89 mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
90 mRenderOp.indexData = new Ogre::IndexData();
91 mRenderOp.vertexData = new Ogre::VertexData();
92 mRenderOp.useIndexes = true;
93
94 // Generate the geometry
95 //radius = ogreParentLight->getAttenuationRange() * 1.2;
96 SBaseMeshsTools::CreateSphere(mRenderOp.vertexData, mRenderOp.indexData, radius, 10, 10, false, false);
97
98 // Set bounding box
99 setBoundingBox(Ogre::AxisAlignedBox(Ogre::Vector3(-radius, -radius, -radius), Ogre::Vector3(radius, radius, radius)));
100 // and sphere radius
101 //radius = newRadius;
102}
103
105{
106 return radius;
107}
108
109Ogre::Real SDeferredLightPoint::getSquaredViewDepth(const Ogre::Camera* cam) const
110{
111 Ogre::Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition();
112 return dist.squaredLength();
113}
114
115void SDeferredLightPoint::getWorldTransforms(Ogre::Matrix4* xform) const
116{
117 xform->makeTransform(ogreParentLight->getDerivedPosition(), Ogre::Vector3::UNIT_SCALE, Ogre::Quaternion::IDENTITY);
118}
119
120void SDeferredLightPoint::CheckCullingMode(Ogre::Camera* camera, Ogre::Pass* pass)
121{
122 pass->setDepthCheckEnabled(true);
123
124 // Check if the camera is inside the sphere geometry (small epsilon fix to account for the fact that we aren't a true sphere).
125 Ogre::Real distanceFromLight = camera->getDerivedPosition().distance(ogreParentLight->getDerivedPosition());
126 if ((distanceFromLight) <= (radius + camera->getNearClipDistance() + 0.01))
127 {
128 pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE);
129 }
130 else
131 {
132 pass->setCullingMode(Ogre::CULL_CLOCKWISE);
133 }
134 pass->setDepthFunction(Ogre::CMPF_ALWAYS_PASS);
135}
136
137}
static Ogre::MeshPtr CreateSphere(const Ogre::String &strName, float radius, int nRings, int nSegments, bool bNormals, bool bTexCoords, Ogre::String groupName=Ogre::RGN_DEFAULT)
Ogre::Light * ogreParentLight
The light that this SDeferredLight renders.
virtual void CheckCullingMode(Ogre::Camera *camera, Ogre::Pass *pass)
virtual void getWorldTransforms(Ogre::Matrix4 *xform) const
virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera *) const
SDeferredLightPoint(Ogre::Light *originalLight, SDeferredLightMaterialGenerator *typeLightMaterialGenerator)
virtual Ogre::Real getBoundingRadius() const