Browse Source

Scene optimizations for shadowing

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
5c32d7cf2f

+ 7 - 7
include/anki/input/Input.h

@@ -19,12 +19,12 @@ public:
 
 	/// @name Acessors
 	/// @{
-	short getKey(uint32_t i) const
+	uint32_t getKey(uint32_t i) const
 	{
 		return keys[i];
 	}
 
-	short getMouseBtn(uint32_t i) const
+	uint32_t getMouseBtn(uint32_t i) const
 	{
 		return mouseBtns[i];
 	}
@@ -54,13 +54,13 @@ private:
 	/// - 0 times: unpressed
 	/// - 1 times: pressed once
 	/// - >1 times: Kept pressed 'n' times continuously
-	std::array<short, SDL_NUM_SCANCODES> keys;
+	std::array<uint32_t, SDL_NUM_SCANCODES> keys;
 
 	/// Mouse btns. Supporting 3 btns & wheel. @see keys
-	std::array<short, 8> mouseBtns;
+	std::array<uint32_t, 8> mouseBtns;
 	/// @}
 
-	bool warpMouseFlag;
+	bool warpMouseFlag = false;
 
 	// mouse stuff
 	Vec2 mousePosNdc; ///< The coords are in the NDC space
@@ -68,13 +68,13 @@ private:
 	/// corner
 	Vec2 mousePos;
 	Vec2 mouseVelocity;
-	bool hideCursor;
+	bool hideCursor = false;
 
 	void init();
 };
 
 typedef Singleton<Input> InputSingleton;
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 1 - 1
include/anki/renderer/Ms.h

@@ -41,6 +41,6 @@ private:
 	Texture depthFai; ///< The FAI for depth
 };
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 11 - 34
include/anki/renderer/Sm.h

@@ -20,11 +20,6 @@ public:
 
 	/// @name Accessors
 	/// @{
-	const Texture& getShadowMap() const
-	{
-		return crntLevel->shadowMap;
-	}
-
 	bool getEnabled() const
 	{
 		return enabled;
@@ -39,11 +34,6 @@ public:
 	{
 		return bilinearEnabled;
 	}
-
-	int getResolution() const
-	{
-		return resolution;
-	}
 	/// @}
 
 	void init(const RendererInitializer& initializer);
@@ -53,43 +43,30 @@ public:
 	/// @param[in] light The light
 	/// @param[in] distance The distance between the viewer's camera and the
 	///            light
-	void run(Light& light, float distance); /// XXX order
+	Texture* run(Light& light, float distance); /// XXX order
 
 private:
-	/// The shadowmap levels of detail
-	/// It starts from level 0 which is the detailed one and moves to lower
-	/// resolution shadowmaps. When the distance between the viewer's
-	/// camera and the light is getting bigger then a higher level will be
-	/// used
-	struct Level
+	struct Shadowmap
 	{
-		Fbo fbo; ///< Illumination stage shadowmapping FBO
-		Texture shadowMap; ///< The shadowmap for that level
-		uint32_t resolution; ///< The shadowmap's resolution
-		bool bilinear; ///< Enable bilinar filtering in shadowmap
-		/// The maximum distance that this level applies. The distance is
-		/// between the viewer's camera and the light
-		float distance;
+		Texture tex;
+		Fbo fbo;
+		Light* light = nullptr;
 	};
 
-	std::array<Level, 4> levels; ///< The levels of detail. The 0 is the
-								   ///< detailed one
-	Level* crntLevel; ///< Current level of detail. Assigned by run
+	static const int MAX_SHADOWMAPS = 5;
+
+	std::array<Shadowmap, MAX_SHADOWMAPS> sms;
 
 	bool enabled; ///< If false then disable SM at all
 	/// Enable Percentage Closer Filtering for all the levels
 	bool pcfEnabled;
 	/// Shadowmap bilinear filtering for the first level. Better quality
 	bool bilinearEnabled;
-	/// Shadowmap resolution of the first level. The higher the better but
-	/// slower
+	/// Shadowmap resolution
 	int resolution;
-	/// The distance of the first level. @see Level::distance
-	float level0Distance;
 
-	/// Initialize a level
-	static void initLevel(uint resolution, float maxDistance,
-		bool bilinear, Level& level);
+	/// XXX
+	Shadowmap& findBestCandidate(Light& light);
 };
 
 

+ 2 - 0
include/anki/scene/Camera.h

@@ -169,6 +169,7 @@ public:
 		updateViewMatrix();
 		updateViewProjectionMatrix();
 		frustum.setTransform(getWorldTransform());
+		spatialMarkUpdated();
 	}
 	/// @}
 
@@ -183,6 +184,7 @@ public:
 		projectionMat = frustum.calculateProjectionMatrix();
 		invProjectionMat = projectionMat.getInverse();
 		updateViewProjectionMatrix();
+		spatialMarkUpdated();
 	}
 	/// @}
 

+ 12 - 0
include/anki/scene/Frustumable.h

@@ -58,10 +58,20 @@ public:
 	{
 		return vinfo;
 	}
+
+	uint32_t getFrustumableLastUpdateFrame() const
+	{
+		return lastUpdateFrame;
+	}
 	/// @}
 
 	/// Called when a frustum parameter changes
 	virtual void frustumUpdate()
+	{
+		spatialMarkUpdated();
+	}
+
+	void spatialMarkUpdated()
 	{
 		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
@@ -81,6 +91,8 @@ public:
 protected:
 	Frustum* frustum = nullptr;
 	VisibilityInfo vinfo;
+
+private:
 	uint32_t lastUpdateFrame = SceneSingleton::get().getFramesCount();
 };
 

+ 8 - 9
include/anki/scene/Light.h

@@ -138,15 +138,12 @@ public:
 	/// @{
 	float getRadius() const
 	{
-		return sphereL.getRadius();
-	}
-	float& getRadius()
-	{
-		return sphereL.getRadius();
+		return sphereW.getRadius();
 	}
 	void setRadius(const float x)
 	{
-		sphereL.setRadius(x);
+		sphereW.setRadius(x);
+		spatialMarkUpdated();
 	}
 	/// @}
 
@@ -158,13 +155,13 @@ public:
 	void movableUpdate()
 	{
 		Movable::movableUpdate();
-		sphereW = sphereL.getTransformed(getWorldTransform());
+		sphereW.setCenter(getWorldTransform().getOrigin());
+		spatialMarkUpdated();
 	}
 	/// @}
 
 public:
-	Sphere sphereW;
-	Sphere sphereL = {Vec3(0.0), 2.0};
+	Sphere sphereW = Sphere(Vec3(0.0), 2.0);
 };
 
 /// Spot light
@@ -240,6 +237,7 @@ public:
 		Movable::movableUpdate();
 		frustum.setTransform(getWorldTransform());
 		viewMat = Mat4(getWorldTransform().getInverse());
+		spatialMarkUpdated();
 	}
 	/// @}
 
@@ -252,6 +250,7 @@ public:
 	{
 		Frustumable::frustumUpdate();
 		projectionMat = frustum.calculateProjectionMatrix();
+		spatialMarkUpdated();
 	}
 	/// @}
 

+ 21 - 11
include/anki/scene/Movable.h

@@ -46,22 +46,22 @@ public:
 	void setLocalTransform(const Transform& x)
 	{
 		lTrf = x;
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void setLocalTranslation(const Vec3& x)
 	{
 		lTrf.setOrigin(x);
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void setLocalRotation(const Mat3& x)
 	{
 		lTrf.setRotation(x);
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void setLocalScale(float x)
 	{
 		lTrf.setScale(x);
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 
 	const Transform& getWorldTransform() const
@@ -73,6 +73,11 @@ public:
 	{
 		return prevWTrf;
 	}
+
+	uint32_t getMovableLastUpdateFrame() const
+	{
+		return lastUpdateFrame;
+	}
 	/// @}
 
 	/// @name Mess with the local transform
@@ -80,40 +85,40 @@ public:
 	void rotateLocalX(float angDegrees)
 	{
 		lTrf.getRotation().rotateXAxis(angDegrees);
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void rotateLocalY(float angDegrees)
 	{
 		lTrf.getRotation().rotateYAxis(angDegrees);
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void rotateLocalZ(float angDegrees)
 	{
 		lTrf.getRotation().rotateZAxis(angDegrees);
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void moveLocalX(float distance)
 	{
 		Vec3 x_axis = lTrf.getRotation().getColumn(0);
 		lTrf.getOrigin() += x_axis * distance;
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void moveLocalY(float distance)
 	{
 		Vec3 y_axis = lTrf.getRotation().getColumn(1);
 		lTrf.getOrigin() += y_axis * distance;
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void moveLocalZ(float distance)
 	{
 		Vec3 z_axis = lTrf.getRotation().getColumn(2);
 		lTrf.getOrigin() += z_axis * distance;
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	void scale(float s)
 	{
 		lTrf.getScale() += s;
-		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+		movableMarkUpdated();
 	}
 	/// @}
 
@@ -146,6 +151,11 @@ protected:
 	/// Called for every frame. It updates the @a wTrf if @a shouldUpdateWTrf
 	/// is true. Then it moves to the children.
 	void updateWorldTransform();
+
+	void movableMarkUpdated()
+	{
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+	}
 };
 /// @}
 

+ 0 - 4
include/anki/scene/Renderable.h

@@ -94,12 +94,8 @@ protected:
 private:
 	MaterialVariableProperties props;
 };
-
-
 /// @}
 
-
 } // end namespace anki
 
-
 #endif

+ 3 - 1
include/anki/scene/SceneNode.h

@@ -86,6 +86,8 @@ public:
 		(void)frame;
 	}
 
+	uint32_t getLastUpdateFrame();
+
 private:
 	std::string name; ///< A unique name
 	Scene* scene; ///< Keep it here for unregistering
@@ -93,7 +95,7 @@ private:
 /// @}
 
 
-} // end namespace
+} // end namespace anki
 
 
 #endif

+ 15 - 1
include/anki/scene/Spatial.h

@@ -34,11 +34,25 @@ public:
 	{
 		return *spatialCs;
 	}
+
+	uint32_t getSpatialLastUpdateFrame() const
+	{
+		return lastUpdateFrame;
+	}
 	/// @}
 
+	/// The derived class has to manually set when the collision shape got
+	/// updated
+	void spatialMarkUpdated()
+	{
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+	}
+
 protected:
 	CollisionShape* spatialCs;
-	uint32_t lastFrameUpdate = SceneSingleton::get().getFramesCount();
+
+private:
+	uint32_t lastUpdateFrame = SceneSingleton::get().getFramesCount();
 };
 /// @}
 

+ 7 - 16
src/input/Input.cpp

@@ -9,8 +9,6 @@ namespace anki {
 void Input::init()
 {
 	ANKI_LOGI("Initializing input...");
-	warpMouseFlag = false;
-	hideCursor = true;
 	reset();
 	ANKI_LOGI("Input initialized");
 }
@@ -18,8 +16,8 @@ void Input::init()
 //==============================================================================
 void Input::reset(void)
 {
-	memset(&keys[0], 0, keys.size() * sizeof(short));
-	memset(&mouseBtns[0], 0, mouseBtns.size() * sizeof(short));
+	memset(&keys[0], 0, keys.size() * sizeof(uint32_t));
+	memset(&mouseBtns[0], 0, mouseBtns.size() * sizeof(uint32_t));
 	mousePosNdc = Vec2(0.0);
 	mouseVelocity = Vec2(0.0);
 }
@@ -27,26 +25,19 @@ void Input::reset(void)
 //==============================================================================
 void Input::handleEvents()
 {
-	if(hideCursor)
-	{
-		SDL_ShowCursor(SDL_DISABLE);
-	}
-	else
-	{
-		SDL_ShowCursor(SDL_ENABLE);
-	}
-
 	// add the times a key is bying pressed
-	for(uint x=0; x<keys.size(); x++)
+	for(uint32_t& k : keys)
 	{
-		if(keys[x]) ++keys[x];
+		if(k)
+		{
+			++k;
+		}
 	}
 	for(int x=0; x<8; x++)
 	{
 		if(mouseBtns[x]) ++mouseBtns[x];
 	}
 
-
 	mouseVelocity = Vec2(0.0);
 
 	SDL_Event event_;

+ 2 - 2
src/renderer/Is.cpp

@@ -223,10 +223,10 @@ void Is::spotLightPass(SpotLight& light)
 	shdr->findUniformVariable("lightTex").set(light.getTexture());
 
 	// the shadowmap
-	if(withShadow)
+	/*if(withShadow)
 	{
 		shdr->findUniformVariable("shadowMap").set(sm.getShadowMap());
-	}
+	}*/
 
 	// render quad
 	r->drawQuad();

+ 6 - 3
src/renderer/Ms.cpp

@@ -26,12 +26,15 @@ void Ms::init(const RendererInitializer& initializer)
 		fbo.create();
 		fbo.setColorAttachments({&fai0});
 		fbo.setOtherAttachment(GL_DEPTH_STENCIL_ATTACHMENT, depthFai);
-		ANKI_ASSERT(fbo.isComplete());
+		if(!fbo.isComplete())
+		{
+			throw ANKI_EXCEPTION("FBO is incomplete");
+		}
 	}
 	catch(std::exception& e)
 	{
 		throw ANKI_EXCEPTION("Cannot create deferred "
-			"shading material stage FBO") << e;
+			"shading material stage") << e;
 	}
 
 	ez.init(initializer);
@@ -86,4 +89,4 @@ void Ms::run()
 	ANKI_CHECK_GL_ERROR();
 }
 
-} // end namespace
+} // end namespace anki

+ 51 - 58
src/renderer/Sm.cpp

@@ -21,91 +21,82 @@ void Sm::init(const RendererInitializer& initializer)
 	pcfEnabled = initializer.is.sm.pcfEnabled;
 	bilinearEnabled = initializer.is.sm.bilinearEnabled;
 	resolution = initializer.is.sm.resolution;
-	level0Distance = initializer.is.sm.level0Distance;
 
-	// Init the levels
-	initLevel(resolution, level0Distance, bilinearEnabled, levels[0]);
-	for(uint32_t i = 1; i < levels.size(); i++)
+	// Init the shadowmaps
+	for(Shadowmap& sm : sms)
 	{
-		initLevel(levels[i - 1].resolution / 2,
-			levels[i - 1].distance * 2.0,
-			bilinearEnabled,
-			levels[i]);
+		Renderer::createFai(resolution, resolution,
+			GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, sm.tex);
+
+		if(bilinearEnabled)
+		{
+			sm.tex.setFiltering(Texture::TFT_LINEAR);
+		}
+		else
+		{
+			sm.tex.setFiltering(Texture::TFT_NEAREST);
+		}
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
+			GL_COMPARE_R_TO_TEXTURE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+
+		sm.fbo.create();
+		sm.fbo.setOtherAttachment(GL_DEPTH_ATTACHMENT, sm.tex);
 	}
 }
 
 //==============================================================================
-void Sm::initLevel(uint32_t resolution, float distance, bool bilinear,
-	Level& level)
+Sm::Shadowmap& Sm::findBestCandidate(Light& light)
 {
-	level.resolution = resolution;
-	level.distance = distance;
-	level.bilinear = bilinear;
+	uint32_t crntFrame = r->getFramesCount();
+	uint32_t minFrame = crntFrame;
+	Shadowmap* best = nullptr;
+	Shadowmap* secondBest = nullptr;
 
-	try
+	// Check if already in list
+	for(Shadowmap& sm : sms)
 	{
-		// Init texture
-		Renderer::createFai(level.resolution, level.resolution,
-			GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, level.shadowMap);
+		uint32_t fr;
 
-		if(level.bilinear)
+		if(sm.light == &light)
 		{
-			level.shadowMap.setFiltering(Texture::TFT_LINEAR);
+			return sm;
 		}
-		else
+		else if(sm.light == nullptr)
 		{
-			level.shadowMap.setFiltering(Texture::TFT_NEAREST);
+			best = &sm;
+		}
+		else if((fr = sm.light->getLastUpdateFrame()) < minFrame)
+		{
+			secondBest = &sm;
+			minFrame = fr;
 		}
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
-			GL_COMPARE_R_TO_TEXTURE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
-		/*If you dont want to use the FFP for comparing the shadowmap
-		(the above two lines) then you can make the comparison
-		inside the glsl shader. The GL_LEQUAL means that:
-		shadow = (R <= Dt) ? 1.0 : 0.0; . The R is given by:
-		R = _tex_coord2.z/_tex_coord2.w; and the
-		Dt = shadow2D(shadow_depth_map, _shadow_uv).r (see lp_generic.frag).
-		Hardware filters like GL_LINEAR cannot be applied.*/
-
-		// create FBO
-		level.fbo.create();
-		level.fbo.setOtherAttachment(GL_DEPTH_ATTACHMENT, level.shadowMap);
-	}
-	catch(std::exception& e)
-	{
-		throw ANKI_EXCEPTION("Cannot create shadowmapping FBO") << e;
 	}
+
+	ANKI_ASSERT(best != nullptr || secondBest != nullptr);
+
+	return (best) ? *best : *secondBest;
 }
 
 //==============================================================================
-void Sm::run(Light& light, float distance)
+Texture* Sm::run(Light& light, float distance)
 {
 	if(!enabled || !light.getShadowEnabled()
 		|| light.getLightType() == Light::LT_POINT)
 	{
-		return;
+		return nullptr;
 	}
 
-	// Determine the level
-	//
-	for(Level& level : levels)
-	{
-		crntLevel = &level;
-		if(distance < level.distance)
-		{
-			break;
-		}
-	}
+	Shadowmap& sm = findBestCandidate(light);
 
 	// Render
 	//
 
 	// FBO
-	crntLevel->fbo.bind();
+	sm.fbo.bind();
 
 	// set GL
-	GlStateSingleton::get().setViewport(0, 0,
-		crntLevel->resolution, crntLevel->resolution);
+	GlStateSingleton::get().setViewport(0, 0, resolution, resolution);
 	glClear(GL_DEPTH_BUFFER_BIT);
 
 	// disable color & blend & enable depth test
@@ -117,12 +108,12 @@ void Sm::run(Light& light, float distance)
 	glPolygonOffset(2.0, 2.0); // keep the values as low as possible!!!!
 	GlStateSingleton::get().enable(GL_POLYGON_OFFSET_FILL);
 
-	// Visibility tests
-	SpotLight& slight = static_cast<SpotLight&>(light);
+	Frustumable* fr = light.getFrustumable();
+	ANKI_ASSERT(fr);
 
 	// render all
-	for(auto it = slight.getVisibilityInfo().getRenderablesBegin();
-		it != slight.getVisibilityInfo().getRenderablesEnd(); ++it)
+	for(auto it = fr->getVisibilityInfo().getRenderablesBegin();
+		it != fr->getVisibilityInfo().getRenderablesEnd(); ++it)
 	{
 		r->getSceneDrawer().render(r->getScene().getActiveCamera(), 1, *(*it));
 	}
@@ -130,6 +121,8 @@ void Sm::run(Light& light, float distance)
 	// restore GL
 	GlStateSingleton::get().disable(GL_POLYGON_OFFSET_FILL);
 	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+	return &sm.tex;
 }
 
 

+ 1 - 4
src/scene/Light.cpp

@@ -37,10 +37,7 @@ PointLight::PointLight(const char* name, Scene* scene,
 	uint32_t movableFlags, Movable* movParent)
 	: Light(LT_POINT, name, scene, movableFlags, movParent, &sphereW)
 {
-	sphereL.setCenter(Vec3(0.0));
-	sphereL.setRadius(1.0);
-
-	float& r = sphereL.getRadius();
+	float& r = sphereW.getRadius();
 	addNewProperty(new ReadWritePointerProperty<float>("radius", &r));
 }
 

+ 26 - 0
src/scene/Scene.cpp

@@ -43,6 +43,32 @@ void Scene::update(float prevUpdateTime, float crntTime)
 	}
 
 	doVisibilityTests(*mainCam);
+
+#if 0
+	for(SceneNode* n : nodes)
+	{
+		if(n->getSpatial()
+			&& n->getSpatial()->getSpatialLastUpdateFrame() == frame)
+		{
+			std::cout << "Spatial updated on: " << n->getName()
+				<< std::endl;
+		}
+
+		if(n->getMovable()
+			&& n->getMovable()->getMovableLastUpdateFrame() == frame)
+		{
+			std::cout << "Movable updated on: " << n->getName()
+				<< std::endl;
+		}
+
+		if(n->getFrustumable()
+			&& n->getFrustumable()->getFrustumableLastUpdateFrame() == frame)
+		{
+			std::cout << "Frustumable updated on: " << n->getName()
+				<< std::endl;
+		}
+	}
+#endif
 }
 
 //==============================================================================

+ 29 - 4
src/scene/SceneNode.cpp

@@ -1,10 +1,11 @@
 #include "anki/scene/SceneNode.h"
 #include "anki/scene/Scene.h"
-
+#include "anki/scene/Movable.h"
+#include "anki/scene/Spatial.h"
+#include "anki/scene/Frustumable.h"
 
 namespace anki {
 
-
 //==============================================================================
 SceneNode::SceneNode(const char* name_, Scene* scene_)
 	: name(name_), scene(scene_)
@@ -15,12 +16,36 @@ SceneNode::SceneNode(const char* name_, Scene* scene_)
 	addNewProperty(new ReadPointerProperty<std::string>("name", &name));
 }
 
-
 //==============================================================================
 SceneNode::~SceneNode()
 {
 	scene->unregisterNode(this);
 }
 
+//==============================================================================
+uint32_t SceneNode::getLastUpdateFrame()
+{
+	uint32_t max = 0;
+
+	const Movable* m = getMovable();
+	if(m && m->getMovableLastUpdateFrame() > max)
+	{
+		max = m->getMovableLastUpdateFrame();
+	}
+
+	const Frustumable* fr = getFrustumable();
+	if(fr && fr->getFrustumableLastUpdateFrame() > max)
+	{
+		max = fr->getFrustumableLastUpdateFrame();
+	}
+
+	const Spatial* s = getSpatial();
+	if(s && s->getSpatialLastUpdateFrame() > max)
+	{
+		max = s->getSpatialLastUpdateFrame();
+	}
+
+	return max;
+}
 
-} // end namespace
+} // end namespace anki

+ 6 - 0
testapp/Main.cpp

@@ -132,6 +132,12 @@ void mainLoopExtra()
 		mover = SceneSingleton::get().findSceneNode("point1")->getMovable();
 	}
 
+	if(in.getKey(SDL_SCANCODE_L) == 1)
+	{
+		Light* l = SceneSingleton::get().findSceneNode("point1")->getLight();
+		static_cast<PointLight*>(l)->setRadius(10.0);
+	}
+
 	if(in.getKey(SDL_SCANCODE_UP)) mover->rotateLocalX(ang);
 	if(in.getKey(SDL_SCANCODE_DOWN)) mover->rotateLocalX(-ang);
 	if(in.getKey(SDL_SCANCODE_LEFT)) mover->rotateLocalY(ang);