diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-04-13 08:40:18 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-04-13 18:01:09 +0200 |
commit | bf90df100e120e272c14c7975a22ed01bf3ad215 (patch) | |
tree | 073f4cf268a7f9407e5ad4a313ae76a619ff1dcc /source/Irrlicht/CLightSceneNode.cpp | |
parent | 7a3fc62ada4001d5bb6c97ed26ec19a4e7c9d9ac (diff) | |
download | irrlicht-bf90df100e120e272c14c7975a22ed01bf3ad215.tar.xz |
Add back lighting system
Code is taken from latest irrlicht trunk; this is relevant because there have been fixes to stencil shadows since 1.8.5 (irrlicht SVN revision 5933).
Diffstat (limited to 'source/Irrlicht/CLightSceneNode.cpp')
-rw-r--r-- | source/Irrlicht/CLightSceneNode.cpp | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/source/Irrlicht/CLightSceneNode.cpp b/source/Irrlicht/CLightSceneNode.cpp new file mode 100644 index 0000000..ac94508 --- /dev/null +++ b/source/Irrlicht/CLightSceneNode.cpp @@ -0,0 +1,233 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "CLightSceneNode.h"
+#include "IVideoDriver.h"
+#include "ISceneManager.h"
+#include "ICameraSceneNode.h"
+
+#include "os.h"
+
+namespace irr
+{
+namespace scene
+{
+
+//! constructor
+CLightSceneNode::CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
+ const core::vector3df& position, video::SColorf color, f32 radius)
+: ILightSceneNode(parent, mgr, id, position), DriverLightIndex(-1), LightIsOn(true)
+{
+ #ifdef _DEBUG
+ setDebugName("CLightSceneNode");
+ #endif
+
+ LightData.DiffuseColor = color;
+ // set some useful specular color
+ LightData.SpecularColor = color.getInterpolated(video::SColor(255,255,255,255),0.7f);
+
+ setRadius(radius);
+}
+
+
+//! pre render event
+void CLightSceneNode::OnRegisterSceneNode()
+{
+ doLightRecalc(); // TODO: since doLightRecalc has now been added to updateAbsolutePosition it might be possible to remove this one.
+
+ if (IsVisible)
+ SceneManager->registerNodeForRendering(this, ESNRP_LIGHT);
+
+ ISceneNode::OnRegisterSceneNode();
+}
+
+
+//! render
+void CLightSceneNode::render()
+{
+ video::IVideoDriver* driver = SceneManager->getVideoDriver();
+ if (!driver)
+ return;
+
+ if ( DebugDataVisible & scene::EDS_BBOX )
+ {
+ driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
+ video::SMaterial m;
+ m.Lighting = false;
+ driver->setMaterial(m);
+
+ switch ( LightData.Type )
+ {
+ case video::ELT_POINT:
+ case video::ELT_SPOT:
+ driver->draw3DBox(BBox, LightData.DiffuseColor.toSColor());
+ break;
+
+ case video::ELT_DIRECTIONAL:
+ driver->draw3DLine(core::vector3df(0.f, 0.f, 0.f),
+ LightData.Direction * LightData.Radius,
+ LightData.DiffuseColor.toSColor());
+ break;
+ default:
+ break;
+ }
+ }
+
+ DriverLightIndex = driver->addDynamicLight(LightData);
+ setVisible(LightIsOn);
+}
+
+
+//! sets the light data
+void CLightSceneNode::setLightData(const video::SLight& light)
+{
+ LightData = light;
+}
+
+
+//! \return Returns the light data.
+const video::SLight& CLightSceneNode::getLightData() const
+{
+ return LightData;
+}
+
+
+//! \return Returns the light data.
+video::SLight& CLightSceneNode::getLightData()
+{
+ return LightData;
+}
+
+void CLightSceneNode::setVisible(bool isVisible)
+{
+ ISceneNode::setVisible(isVisible);
+
+ if(DriverLightIndex < 0)
+ return;
+ video::IVideoDriver* driver = SceneManager->getVideoDriver();
+ if (!driver)
+ return;
+
+ LightIsOn = isVisible;
+ driver->turnLightOn((u32)DriverLightIndex, LightIsOn);
+}
+
+//! returns the axis aligned bounding box of this node
+const core::aabbox3d<f32>& CLightSceneNode::getBoundingBox() const
+{
+ return BBox;
+}
+
+
+//! Sets the light's radius of influence.
+/** Outside this radius the light won't lighten geometry and cast no
+shadows. Setting the radius will also influence the attenuation, setting
+it to (0,1/radius,0). If you want to override this behavior, set the
+attenuation after the radius.
+\param radius The new radius. */
+void CLightSceneNode::setRadius(f32 radius)
+{
+ LightData.Radius=radius;
+ LightData.Attenuation.set(0.f, 1.f/radius, 0.f);
+ doLightRecalc();
+}
+
+
+//! Gets the light's radius of influence.
+/** \return The current radius. */
+f32 CLightSceneNode::getRadius() const
+{
+ return LightData.Radius;
+}
+
+
+//! Sets the light type.
+/** \param type The new type. */
+void CLightSceneNode::setLightType(video::E_LIGHT_TYPE type)
+{
+ LightData.Type=type;
+}
+
+
+//! Gets the light type.
+/** \return The current light type. */
+video::E_LIGHT_TYPE CLightSceneNode::getLightType() const
+{
+ return LightData.Type;
+}
+
+
+//! Sets whether this light casts shadows.
+/** Enabling this flag won't automatically cast shadows, the meshes
+will still need shadow scene nodes attached. But one can enable or
+disable distinct lights for shadow casting for performance reasons.
+\param shadow True if this light shall cast shadows. */
+void CLightSceneNode::enableCastShadow(bool shadow)
+{
+ LightData.CastShadows=shadow;
+}
+
+
+//! Check whether this light casts shadows.
+/** \return True if light would cast shadows, else false. */
+bool CLightSceneNode::getCastShadow() const
+{
+ return LightData.CastShadows;
+}
+
+
+void CLightSceneNode::doLightRecalc()
+{
+ if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL))
+ {
+ LightData.Direction = core::vector3df(.0f,.0f,1.0f);
+ getAbsoluteTransformation().rotateVect(LightData.Direction);
+ LightData.Direction.normalize();
+ }
+ if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT))
+ {
+ const f32 r = LightData.Radius * LightData.Radius * 0.5f;
+ BBox.MaxEdge.set( r, r, r );
+ BBox.MinEdge.set( -r, -r, -r );
+ //setAutomaticCulling( scene::EAC_BOX );
+ setAutomaticCulling( scene::EAC_OFF );
+ LightData.Position = getAbsolutePosition();
+ }
+ if (LightData.Type == video::ELT_DIRECTIONAL)
+ {
+ BBox.reset( 0, 0, 0 );
+ setAutomaticCulling( scene::EAC_OFF );
+ }
+}
+
+void CLightSceneNode::updateAbsolutePosition()
+{
+ ILightSceneNode::updateAbsolutePosition();
+ doLightRecalc();
+}
+
+
+//! Creates a clone of this scene node and its children.
+ISceneNode* CLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
+{
+ if (!newParent)
+ newParent = Parent;
+ if (!newManager)
+ newManager = SceneManager;
+
+ CLightSceneNode* nb = new CLightSceneNode(newParent,
+ newManager, ID, RelativeTranslation, LightData.DiffuseColor, LightData.Radius);
+
+ nb->cloneMembers(this, newManager);
+ nb->LightData = LightData;
+ nb->BBox = BBox;
+
+ if ( newParent )
+ nb->drop();
+ return nb;
+}
+
+} // end namespace scene
+} // end namespace irr
+
|