diff options
Diffstat (limited to 'libraries/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp')
-rw-r--r-- | libraries/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp b/libraries/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp new file mode 100644 index 0000000..55b6337 --- /dev/null +++ b/libraries/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp | |||
@@ -0,0 +1,275 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "CLightSceneNode.h" | ||
6 | #include "IVideoDriver.h" | ||
7 | #include "ISceneManager.h" | ||
8 | #include "ICameraSceneNode.h" | ||
9 | |||
10 | #include "os.h" | ||
11 | |||
12 | namespace irr | ||
13 | { | ||
14 | namespace scene | ||
15 | { | ||
16 | |||
17 | //! constructor | ||
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) | ||
21 | { | ||
22 | #ifdef _DEBUG | ||
23 | setDebugName("CLightSceneNode"); | ||
24 | #endif | ||
25 | |||
26 | LightData.DiffuseColor = color; | ||
27 | // set some useful specular color | ||
28 | LightData.SpecularColor = color.getInterpolated(video::SColor(255,255,255,255),0.7f); | ||
29 | |||
30 | setRadius(radius); | ||
31 | } | ||
32 | |||
33 | |||
34 | //! pre render event | ||
35 | void CLightSceneNode::OnRegisterSceneNode() | ||
36 | { | ||
37 | doLightRecalc(); | ||
38 | |||
39 | if (IsVisible) | ||
40 | SceneManager->registerNodeForRendering(this, ESNRP_LIGHT); | ||
41 | |||
42 | ISceneNode::OnRegisterSceneNode(); | ||
43 | } | ||
44 | |||
45 | |||
46 | //! render | ||
47 | void CLightSceneNode::render() | ||
48 | { | ||
49 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | ||
50 | if (!driver) | ||
51 | return; | ||
52 | |||
53 | if ( DebugDataVisible & scene::EDS_BBOX ) | ||
54 | { | ||
55 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | ||
56 | video::SMaterial m; | ||
57 | m.Lighting = false; | ||
58 | driver->setMaterial(m); | ||
59 | |||
60 | switch ( LightData.Type ) | ||
61 | { | ||
62 | case video::ELT_POINT: | ||
63 | case video::ELT_SPOT: | ||
64 | driver->draw3DBox(BBox, LightData.DiffuseColor.toSColor()); | ||
65 | break; | ||
66 | |||
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()); | ||
71 | break; | ||
72 | default: | ||
73 | break; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | DriverLightIndex = driver->addDynamicLight(LightData); | ||
78 | setVisible(LightIsOn); | ||
79 | } | ||
80 | |||
81 | |||
82 | //! sets the light data | ||
83 | void CLightSceneNode::setLightData(const video::SLight& light) | ||
84 | { | ||
85 | LightData = light; | ||
86 | } | ||
87 | |||
88 | |||
89 | //! \return Returns the light data. | ||
90 | const video::SLight& CLightSceneNode::getLightData() const | ||
91 | { | ||
92 | return LightData; | ||
93 | } | ||
94 | |||
95 | |||
96 | //! \return Returns the light data. | ||
97 | video::SLight& CLightSceneNode::getLightData() | ||
98 | { | ||
99 | return LightData; | ||
100 | } | ||
101 | |||
102 | void CLightSceneNode::setVisible(bool isVisible) | ||
103 | { | ||
104 | ISceneNode::setVisible(isVisible); | ||
105 | |||
106 | if(DriverLightIndex < 0) | ||
107 | return; | ||
108 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | ||
109 | if (!driver) | ||
110 | return; | ||
111 | |||
112 | LightIsOn = isVisible; | ||
113 | driver->turnLightOn((u32)DriverLightIndex, LightIsOn); | ||
114 | } | ||
115 | |||
116 | //! returns the axis aligned bounding box of this node | ||
117 | const core::aabbox3d<f32>& CLightSceneNode::getBoundingBox() const | ||
118 | { | ||
119 | return BBox; | ||
120 | } | ||
121 | |||
122 | |||
123 | //! Sets the light's radius of influence. | ||
124 | /** Outside this radius the light won't lighten geometry and cast no | ||
125 | shadows. Setting the radius will also influence the attenuation, setting | ||
126 | it to (0,1/radius,0). If you want to override this behavior, set the | ||
127 | attenuation after the radius. | ||
128 | \param radius The new radius. */ | ||
129 | void CLightSceneNode::setRadius(f32 radius) | ||
130 | { | ||
131 | LightData.Radius=radius; | ||
132 | LightData.Attenuation.set(0.f, 1.f/radius, 0.f); | ||
133 | doLightRecalc(); | ||
134 | } | ||
135 | |||
136 | |||
137 | //! Gets the light's radius of influence. | ||
138 | /** \return The current radius. */ | ||
139 | f32 CLightSceneNode::getRadius() const | ||
140 | { | ||
141 | return LightData.Radius; | ||
142 | } | ||
143 | |||
144 | |||
145 | //! Sets the light type. | ||
146 | /** \param type The new type. */ | ||
147 | void CLightSceneNode::setLightType(video::E_LIGHT_TYPE type) | ||
148 | { | ||
149 | LightData.Type=type; | ||
150 | } | ||
151 | |||
152 | |||
153 | //! Gets the light type. | ||
154 | /** \return The current light type. */ | ||
155 | video::E_LIGHT_TYPE CLightSceneNode::getLightType() const | ||
156 | { | ||
157 | return LightData.Type; | ||
158 | } | ||
159 | |||
160 | |||
161 | //! Sets whether this light casts shadows. | ||
162 | /** Enabling this flag won't automatically cast shadows, the meshes | ||
163 | will still need shadow scene nodes attached. But one can enable or | ||
164 | disable distinct lights for shadow casting for performance reasons. | ||
165 | \param shadow True if this light shall cast shadows. */ | ||
166 | void CLightSceneNode::enableCastShadow(bool shadow) | ||
167 | { | ||
168 | LightData.CastShadows=shadow; | ||
169 | } | ||
170 | |||
171 | |||
172 | //! Check whether this light casts shadows. | ||
173 | /** \return True if light would cast shadows, else false. */ | ||
174 | bool CLightSceneNode::getCastShadow() const | ||
175 | { | ||
176 | return LightData.CastShadows; | ||
177 | } | ||
178 | |||
179 | |||
180 | void CLightSceneNode::doLightRecalc() | ||
181 | { | ||
182 | if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL)) | ||
183 | { | ||
184 | LightData.Direction = core::vector3df(.0f,.0f,1.0f); | ||
185 | getAbsoluteTransformation().rotateVect(LightData.Direction); | ||
186 | LightData.Direction.normalize(); | ||
187 | } | ||
188 | if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT)) | ||
189 | { | ||
190 | const f32 r = LightData.Radius * LightData.Radius * 0.5f; | ||
191 | BBox.MaxEdge.set( r, r, r ); | ||
192 | BBox.MinEdge.set( -r, -r, -r ); | ||
193 | //setAutomaticCulling( scene::EAC_BOX ); | ||
194 | setAutomaticCulling( scene::EAC_OFF ); | ||
195 | LightData.Position = getAbsolutePosition(); | ||
196 | } | ||
197 | if (LightData.Type == video::ELT_DIRECTIONAL) | ||
198 | { | ||
199 | BBox.reset( 0, 0, 0 ); | ||
200 | setAutomaticCulling( scene::EAC_OFF ); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | |||
205 | //! Writes attributes of the scene node. | ||
206 | void CLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | ||
207 | { | ||
208 | ILightSceneNode::serializeAttributes(out, options); | ||
209 | |||
210 | out->addColorf ("AmbientColor", LightData.AmbientColor); | ||
211 | out->addColorf ("DiffuseColor", LightData.DiffuseColor); | ||
212 | out->addColorf ("SpecularColor", LightData.SpecularColor); | ||
213 | out->addVector3d("Attenuation", LightData.Attenuation); | ||
214 | out->addFloat ("Radius", LightData.Radius); | ||
215 | out->addFloat ("OuterCone", LightData.OuterCone); | ||
216 | out->addFloat ("InnerCone", LightData.InnerCone); | ||
217 | out->addFloat ("Falloff", LightData.Falloff); | ||
218 | out->addBool ("CastShadows", LightData.CastShadows); | ||
219 | out->addEnum ("LightType", LightData.Type, video::LightTypeNames); | ||
220 | } | ||
221 | |||
222 | //! Reads attributes of the scene node. | ||
223 | void CLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | ||
224 | { | ||
225 | LightData.AmbientColor = in->getAttributeAsColorf("AmbientColor"); | ||
226 | LightData.DiffuseColor = in->getAttributeAsColorf("DiffuseColor"); | ||
227 | LightData.SpecularColor = in->getAttributeAsColorf("SpecularColor"); | ||
228 | |||
229 | //TODO: clearify Radius and Linear Attenuation | ||
230 | #if 0 | ||
231 | setRadius ( in->getAttributeAsFloat("Radius") ); | ||
232 | #else | ||
233 | LightData.Radius = in->getAttributeAsFloat("Radius"); | ||
234 | #endif | ||
235 | |||
236 | if (in->existsAttribute("Attenuation")) // might not exist in older files | ||
237 | LightData.Attenuation = in->getAttributeAsVector3d("Attenuation"); | ||
238 | |||
239 | if (in->existsAttribute("OuterCone")) // might not exist in older files | ||
240 | LightData.OuterCone = in->getAttributeAsFloat("OuterCone"); | ||
241 | if (in->existsAttribute("InnerCone")) // might not exist in older files | ||
242 | LightData.InnerCone = in->getAttributeAsFloat("InnerCone"); | ||
243 | if (in->existsAttribute("Falloff")) // might not exist in older files | ||
244 | LightData.Falloff = in->getAttributeAsFloat("Falloff"); | ||
245 | LightData.CastShadows = in->getAttributeAsBool("CastShadows"); | ||
246 | LightData.Type = (video::E_LIGHT_TYPE)in->getAttributeAsEnumeration("LightType", video::LightTypeNames); | ||
247 | |||
248 | doLightRecalc (); | ||
249 | |||
250 | ILightSceneNode::deserializeAttributes(in, options); | ||
251 | } | ||
252 | |||
253 | //! Creates a clone of this scene node and its children. | ||
254 | ISceneNode* CLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) | ||
255 | { | ||
256 | if (!newParent) | ||
257 | newParent = Parent; | ||
258 | if (!newManager) | ||
259 | newManager = SceneManager; | ||
260 | |||
261 | CLightSceneNode* nb = new CLightSceneNode(newParent, | ||
262 | newManager, ID, RelativeTranslation, LightData.DiffuseColor, LightData.Radius); | ||
263 | |||
264 | nb->cloneMembers(this, newManager); | ||
265 | nb->LightData = LightData; | ||
266 | nb->BBox = BBox; | ||
267 | |||
268 | if ( newParent ) | ||
269 | nb->drop(); | ||
270 | return nb; | ||
271 | } | ||
272 | |||
273 | } // end namespace scene | ||
274 | } // end namespace irr | ||
275 | |||