Project

General

Profile

SO3Engine
SO3DeferredLightSpot.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
30SDeferredLightSpot::SDeferredLightSpot(Ogre::Light* originalLight, SDeferredLightMaterialGenerator* typeLightMaterialGenerator) : SDeferredLightImpl(originalLight, "Spot", typeLightMaterialGenerator)
31{
32}
33
37
41
43{
44 // Do not take care about new radius
45 Ogre::Real height = ogreParentLight->getAttenuationRange();
46 Ogre::Radian coneRadiusAngle = std::min<Ogre::Radian>(ogreParentLight->getSpotlightOuterAngle(), Ogre::Degree(179.0f)) / 2; // Avoid Pi/2 max angle
47 Ogre::Real newRadius = Ogre::Math::Tan(coneRadiusAngle) * height;
48
49 delete mRenderOp.vertexData;
50 delete mRenderOp.indexData;
51 mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
52 mRenderOp.indexData = new Ogre::IndexData();
53 mRenderOp.vertexData = new Ogre::VertexData();
54 mRenderOp.useIndexes = true;
55
56 // Generate the geometry
57 SBaseMeshsTools::CreateCone(mRenderOp.vertexData, mRenderOp.indexData, newRadius, height, 20);
58
59 // Set bounding box
60 setBoundingBox(Ogre::AxisAlignedBox(Ogre::Vector3(-newRadius, 0, -newRadius), Ogre::Vector3(newRadius, height, newRadius)));
61 //mRadius = newRadius;
62}
63
65{
66 // TODO
67 return 0.0f;
68}
69
70Ogre::Real SDeferredLightSpot::getSquaredViewDepth(const Ogre::Camera* cam) const
71{
72 Ogre::Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition();
73 return dist.squaredLength();
74}
75
76void SDeferredLightSpot::getWorldTransforms(Ogre::Matrix4* xform) const
77{
78 Ogre::Quaternion quat = Ogre::Vector3::UNIT_Y.getRotationTo(ogreParentLight->getDerivedDirection());
79 xform->makeTransform(ogreParentLight->getDerivedPosition(), Ogre::Vector3::UNIT_SCALE, quat);
80}
81
82void SDeferredLightSpot::CheckCullingMode(Ogre::Camera* camera, Ogre::Pass* pass)
83{
84 // Check if the camera is inside the sphere geometry (small epsilon fix to account for the fact that we aren't a true sphere).
85 Ogre::Vector3 lightPos = ogreParentLight->getDerivedPosition();
86 Ogre::Vector3 lightDir = ogreParentLight->getDerivedDirection();
87 Ogre::Radian attAngle = std::min<Ogre::Radian>(ogreParentLight->getSpotlightOuterAngle(), Ogre::Degree(179.0f));
88
89 //Some trigonometry needed here.
90 Ogre::Vector3 lightToCamDir = camera->getDerivedPosition() - lightPos;
91 //Extend the analytic cone's radius by the near clip range by moving its tip accordingly.
92 Ogre::Vector3 clipRangeFix = -lightToCamDir * Ogre::Math::Tan(attAngle/2);
93 Ogre::Real distanceFromLight = lightToCamDir.normalise() + camera->getNearClipDistance();
94
95 Ogre::Real cosAngle = lightToCamDir.dotProduct(lightDir);
96 Ogre::Radian angle = Ogre::Math::ACos(cosAngle);
97
98 //Check whether we will see the cone from our current POV.
99 if ((distanceFromLight < (ogreParentLight->getAttenuationRange() + clipRangeFix.length())) && (angle <= attAngle))
100 {
101 pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE);
102 //pass->setDepthFunction(Ogre::CMPF_GREATER_EQUAL);
103 }
104 else
105 {
106 pass->setCullingMode(Ogre::CULL_CLOCKWISE);
107 //pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
108 }
109 pass->setDepthCheckEnabled(true);
110 pass->setDepthFunction(Ogre::CMPF_ALWAYS_PASS);
111}
112
113}
static Ogre::MeshPtr CreateCone(const Ogre::String &strName, float radius, float height, int nVerticesInBase, Ogre::String groupName=Ogre::RGN_DEFAULT)
Ogre::Light * ogreParentLight
The light that this SDeferredLight renders.
virtual void getWorldTransforms(Ogre::Matrix4 *xform) const
SDeferredLightSpot(Ogre::Light *originalLight, SDeferredLightMaterialGenerator *typeLightMaterialGenerator)
virtual void CheckCullingMode(Ogre::Camera *camera, Ogre::Pass *pass)
virtual Ogre::Real getBoundingRadius() const
virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera *) const