1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
#include "CLightSceneNode.h"
6
#include "IVideoDriver.h"
7
#include "ISceneManager.h"
8
#include "ICameraSceneNode.h"
18
CLightSceneNode::CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
19
const core::vector3df& position, video::SColorf color, f32 radius)
20
: ILightSceneNode(parent, mgr, id, position), DriverLightIndex(-1), LightIsOn(true)
23
setDebugName("CLightSceneNode");
26
LightData.DiffuseColor = color;
27
// set some useful specular color
28
LightData.SpecularColor = color.getInterpolated(video::SColor(255,255,255,255),0.7f);
35
void CLightSceneNode::OnRegisterSceneNode()
40
SceneManager->registerNodeForRendering(this, ESNRP_LIGHT);
42
ISceneNode::OnRegisterSceneNode();
47
void CLightSceneNode::render()
49
video::IVideoDriver* driver = SceneManager->getVideoDriver();
53
if ( DebugDataVisible & scene::EDS_BBOX )
55
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
58
driver->setMaterial(m);
60
switch ( LightData.Type )
62
case video::ELT_POINT:
64
driver->draw3DBox(BBox, LightData.DiffuseColor.toSColor());
67
case video::ELT_DIRECTIONAL:
68
driver->draw3DLine(core::vector3df(0.f, 0.f, 0.f),
69
LightData.Direction * LightData.Radius,
70
LightData.DiffuseColor.toSColor());
75
DriverLightIndex = driver->addDynamicLight(LightData);
76
setVisible(LightIsOn);
80
//! sets the light data
81
void CLightSceneNode::setLightData(const video::SLight& light)
87
//! \return Returns the light data.
88
const video::SLight& CLightSceneNode::getLightData() const
94
//! \return Returns the light data.
95
video::SLight& CLightSceneNode::getLightData()
100
void CLightSceneNode::setVisible(bool isVisible)
102
ISceneNode::setVisible(isVisible);
104
if(DriverLightIndex < 0)
106
video::IVideoDriver* driver = SceneManager->getVideoDriver();
110
LightIsOn = isVisible;
111
driver->turnLightOn((u32)DriverLightIndex, LightIsOn);
114
//! returns the axis aligned bounding box of this node
115
const core::aabbox3d<f32>& CLightSceneNode::getBoundingBox() const
121
//! Sets the light's radius of influence.
122
/** Outside this radius the light won't lighten geometry and cast no
123
shadows. Setting the radius will also influence the attenuation, setting
124
it to (0,1/radius,0). If you want to override this behavior, set the
125
attenuation after the radius.
126
\param radius The new radius. */
127
void CLightSceneNode::setRadius(f32 radius)
129
LightData.Radius=radius;
130
LightData.Attenuation.set(0.f, 1.f/radius, 0.f);
135
//! Gets the light's radius of influence.
136
/** \return The current radius. */
137
f32 CLightSceneNode::getRadius() const
139
return LightData.Radius;
143
//! Sets the light type.
144
/** \param type The new type. */
145
void CLightSceneNode::setLightType(video::E_LIGHT_TYPE type)
151
//! Gets the light type.
152
/** \return The current light type. */
153
video::E_LIGHT_TYPE CLightSceneNode::getLightType() const
155
return LightData.Type;
159
//! Sets whether this light casts shadows.
160
/** Enabling this flag won't automatically cast shadows, the meshes
161
will still need shadow scene nodes attached. But one can enable or
162
disable distinct lights for shadow casting for performance reasons.
163
\param shadow True if this light shall cast shadows. */
164
void CLightSceneNode::enableCastShadow(bool shadow)
166
LightData.CastShadows=shadow;
170
//! Check whether this light casts shadows.
171
/** \return True if light would cast shadows, else false. */
172
bool CLightSceneNode::getCastShadow() const
174
return LightData.CastShadows;
178
void CLightSceneNode::doLightRecalc()
180
if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL))
182
LightData.Direction = core::vector3df(.0f,.0f,1.0f);
183
getAbsoluteTransformation().rotateVect(LightData.Direction);
184
LightData.Direction.normalize();
186
if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT))
188
const f32 r = LightData.Radius * LightData.Radius * 0.5f;
189
BBox.MaxEdge.set( r, r, r );
190
BBox.MinEdge.set( -r, -r, -r );
191
//setAutomaticCulling( scene::EAC_BOX );
192
setAutomaticCulling( scene::EAC_OFF );
193
LightData.Position = getAbsolutePosition();
195
if (LightData.Type == video::ELT_DIRECTIONAL)
197
BBox.reset( 0, 0, 0 );
198
setAutomaticCulling( scene::EAC_OFF );
203
//! Writes attributes of the scene node.
204
void CLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
206
ILightSceneNode::serializeAttributes(out, options);
208
out->addColorf ("AmbientColor", LightData.AmbientColor);
209
out->addColorf ("DiffuseColor", LightData.DiffuseColor);
210
out->addColorf ("SpecularColor", LightData.SpecularColor);
211
out->addVector3d("Attenuation", LightData.Attenuation);
212
out->addFloat ("Radius", LightData.Radius);
213
out->addFloat ("OuterCone", LightData.OuterCone);
214
out->addFloat ("InnerCone", LightData.InnerCone);
215
out->addFloat ("Falloff", LightData.Falloff);
216
out->addBool ("CastShadows", LightData.CastShadows);
217
out->addEnum ("LightType", LightData.Type, video::LightTypeNames);
220
//! Reads attributes of the scene node.
221
void CLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
223
LightData.AmbientColor = in->getAttributeAsColorf("AmbientColor");
224
LightData.DiffuseColor = in->getAttributeAsColorf("DiffuseColor");
225
LightData.SpecularColor = in->getAttributeAsColorf("SpecularColor");
227
//TODO: clearify Radius and Linear Attenuation
229
setRadius ( in->getAttributeAsFloat("Radius") );
231
LightData.Radius = in->getAttributeAsFloat("Radius");
234
if (in->existsAttribute("Attenuation")) // might not exist in older files
235
LightData.Attenuation = in->getAttributeAsVector3d("Attenuation");
237
if (in->existsAttribute("OuterCone")) // might not exist in older files
238
LightData.OuterCone = in->getAttributeAsFloat("OuterCone");
239
if (in->existsAttribute("InnerCone")) // might not exist in older files
240
LightData.InnerCone = in->getAttributeAsFloat("InnerCone");
241
if (in->existsAttribute("Falloff")) // might not exist in older files
242
LightData.Falloff = in->getAttributeAsFloat("Falloff");
243
LightData.CastShadows = in->getAttributeAsBool("CastShadows");
244
LightData.Type = (video::E_LIGHT_TYPE)in->getAttributeAsEnumeration("LightType", video::LightTypeNames);
248
ILightSceneNode::deserializeAttributes(in, options);
251
//! Creates a clone of this scene node and its children.
252
ISceneNode* CLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
257
newManager = SceneManager;
259
CLightSceneNode* nb = new CLightSceneNode(newParent,
260
newManager, ID, RelativeTranslation, LightData.DiffuseColor, LightData.Radius);
262
nb->cloneMembers(this, newManager);
263
nb->LightData = LightData;
271
} // end namespace scene
272
} // end namespace irr