Jump to content

Creating a rotating light


DaveLee
 Share

Recommended Posts

Hey everyone! I've been experimenting with creating a rotating emergency light (similar to those seen in STALKER). My initial plan was to create a spinning light case and put a point light inside of that. It worked, but there were a few shadow artifacts that I could never completelu get rid of due to how close the point light and spinning model were.

 

My next idea was to remove the animation from the model, and attach two spot lights to it via LUA scripts like this:

 

>o<

 

...and then I would rotate the entire model+lights setup via LUA.

 

The problem is, I'm not a programmer by any means. B) I was able to get one spotlight attached to the model, but I'm at a loss about how to rotate it.

 

Does anyone have any suggestions?

 

Here's my code so far (the light is facing down the wrong axis atm):

 

require("scripts/class")

local class=CreateClass(...)

beginframe1  =  0
endframe1    = 81

class.sound_ambient=LoadSound('abstract::ambient_lighthum.ogg')

function class:InitDialog(grid)
self.super:InitDialog(grid)
group=grid:FindGroup( "Appearance" )
group:AddProperty("castshadows",PROPERTY_CHOICE,"Disabled,Dynamic,Static,Dynamic + Static,Dynamic + Static + Buffered","Cast shadows")	
group=grid:AddGroup("Light")
group:AddProperty("shadowresolution",PROPERTY_CHOICE,"256,512,1024,2048","Shadow resolution")
group:AddProperty("linearoffset",PROPERTY_FLOAT,"0,1,2","Linear offset")
group:AddProperty("Range",PROPERTY_FLOAT,"1,100,0")
group:AddProperty("coneangles",PROPERTY_VEC2,"0,180","Cone angles")
group:Expand(1)
end

function class:CreateObject(model)
local object=self.super:CreateObject(model)
object.light=CreateSpotLight(10,model)	
object.light:SetShadowMode(1+2+4)
object.light:SetRotationf( 1,1,1, 1 )

function object:SetKey(key,value)
	if key=="shadowresolution" then
		if value=="0" then
			self.light:SetShadowmapSize(256)
		elseif value=="1" then
			self.light:SetShadowmapSize(512)
		elseif value=="2" then
			self.light:SetShadowmapSize(1024)
		elseif value=="3" then
			self.light:SetShadowmapSize(2048)
		end
	elseif key=="castshadows" then
		local mode=tonumber(value)
		if mode==0 then
			self.light:SetShadowMode(0)
		elseif mode==1 then
			self.light:SetShadowMode(1)
		elseif mode==2 then
			self.light:SetShadowMode(2)
		elseif mode==3 then
			self.light:SetShadowMode(3)
		elseif mode==4
			then self.light:SetShadowMode(7)
		end
	elseif key=="coneangles" then
		local angles=StringToVec2(value)
		self.light:SetConeAngles( angles.x, angles.y )
	elseif key=="range" then
		self.light:SetRange(value)
	elseif key=="castshadows" then
	--	local mode=tonumber(value)--+4
	--	self.model:SetShadowMode(mode,1)
	elseif key=="multoffset" then
		self.light:SetShadowOffset(self.light:GetShadowOffset(0,0),value,0)
	elseif key=="linearoffset" then
		self.light:SetShadowOffset(value,self.light:GetShadowOffset(1,0),0)
	else
		return self.super:SetKey(key,value)
	end
	return 1
end

function object:GetKey(key,value)
	if key=="linearoffset" then
		return self.light:GetShadowOffset(0,0)
	elseif key=="castshadows" then
		local mode=self.light:GetShadowMode()
		if mode==0 then
			return 0
		elseif mode==1 then
			return 1
		elseif mode==2 then
			return 3
		elseif mode==3 then
			return 3
		elseif mode==7 then
			return 4
		end
	elseif key=="multoffset" then
		return self.light:GetShadowOffset(1,0)
	elseif key=="coneangles" then
		return self.light.innerconeangle..","..self.light.outerconeangle
	elseif key=="shadowresolution" then
		resolution=self.light:GetShadowmapSize()
		if resolution==256 then
			return 0
		elseif resolution==512 then
			return 1
		elseif resolution==1024 then
			return 2	
		elseif resolution==2048 then
			return 3
		else
			return -1
		end
	elseif key=="range" then
		return self.light:GetRange()
	else
		return self.super:GetKey(key,value)
	end
	return value
end

end



Link to comment
Share on other sites

Hi,

haven't tried your code but I'm guessing you're parenting to the whole model when instead you only need a small part of it rotating.

You can create a pivot (invisible entity) by using something like

 

lampPivot = CreatePivot()

 

then attach lights to it by

light = createSpotLight(10,lampPivot)

 

now you can

turnEntity(lampPivot,vec3(0,1,0))

 

on every update

desktop: Quad core Q6600 + 4GB + ATI HD4890 + XP

laptop: Dual core T6400 + 4 GB + NVidia 9600M GT + Vista 32

Link to comment
Share on other sites

great,

thx for sharing. :)

 

 

FYI - need to change for le 2.31

 


require("scripts/class")

local class=CreateClass(...)

function class:InitDialog(grid)
self.super:InitDialog(grid)
group=grid:FindGroup( "Appearance" )
group:AddProperty("castshadows",PROPERTY_CHOICE,"Disabled,Dynamic,Static,Dynamic + Static,Dynamic + Static + Buffered","Cast shadows")	

group=grid:AddGroup("Light")
group:AddProperty("shadowresolution",PROPERTY_CHOICE,"256,512,1024,2048","Shadow resolution")
group:AddProperty("linearoffset",PROPERTY_FLOAT,"0,1,2","Linear offset")
group:AddProperty("Range",PROPERTY_FLOAT,"1,100,0")
group:AddProperty("coneangles",PROPERTY_VEC2,"0,180","Cone angles")

group=grid:AddGroup("Rotation")
group:AddProperty("rotationspeed",PROPERTY_VEC3,"Rotation Speed")
group:Expand(1)
end

function class:CreateObject(model)
local object = self.super:CreateObject(model)

local lampPivot = CreatePivot()
--MoveEntity(lampPivot, EntityPosition(object.model))

EntityParent(lampPivot, object.model, 0)

object.light=CreateSpotLight(5, lampPivot)	
object.light:SetShadowMode(1+2+4)
object.model:SetKey("rotationspeed","0.0,1.0,0.0")

function object:SetKey(key,value)
	if key=="shadowresolution" then
		if value=="0" then
			self.light:SetShadowmapSize(256)
		elseif value=="1" then
			self.light:SetShadowmapSize(512)
		elseif value=="2" then
			self.light:SetShadowmapSize(1024)
		elseif value=="3" then
			self.light:SetShadowmapSize(2048)
		end
	elseif key=="castshadows" then
		local mode=tonumber(value)
		if mode==0 then
			self.light:SetShadowMode(0)
		elseif mode==1 then
			self.light:SetShadowMode(1)
		elseif mode==2 then
			self.light:SetShadowMode(2)
		elseif mode==3 then
			self.light:SetShadowMode(3)
		elseif mode==4
			then self.light:SetShadowMode(7)
		end
	elseif key=="coneangles" then
		local angles=StringToVec2(value)
		self.light:SetConeAngles( angles.x, angles.y )
	elseif key=="range" then
		self.light:SetRange(value)
	elseif key=="castshadows" then
	--	local mode=tonumber(value)--+4
	--	self.model:SetShadowMode(mode,1)
	elseif key=="multoffset" then
		self.light:SetShadowOffset(self.light:GetShadowOffset(0,0),value,0)
	elseif key=="linearoffset" then
		self.light:SetShadowOffset(value,self.light:GetShadowOffset(1,0),0)
	elseif key=="rotationspeed" then
                       self.rotationspeed = StringToVec3(value)
	else
		return self.super:SetKey(key,value)
	end
	return 1
end

function object:GetKey(key,value)
	if key=="linearoffset" then
		return self.light:GetShadowOffset(0,0)
	elseif key=="castshadows" then
		local mode=self.light:GetShadowMode()
		if mode==0 then
			return 0
		elseif mode==1 then
			return 1
		elseif mode==2 then
			return 3
		elseif mode==3 then
			return 3
		elseif mode==7 then
			return 4
		end
	elseif key=="multoffset" then
		return self.light:GetShadowOffset(1,0)
	elseif key=="coneangles" then
		return self.light.innerconeangle..","..self.light.outerconeangle
	elseif key=="shadowresolution" then
		resolution=self.light:GetShadowmapSize()
		if resolution==256 then
			return 0
		elseif resolution==512 then
			return 1
		elseif resolution==1024 then
			return 2	
		elseif resolution==2048 then
			return 3
		else
			return -1
		end
	elseif key=="range" then
		return self.light:GetRange()
	else
		return self.super:GetKey(key,value)
	end
	return value
end

function object:Update() -- Le 2.32 uses Draw() ?!
               lampPivot:Turn(self.rotationspeed,0)
       end

end

AMD 64 X2 Dual 5k - 4GB - XFX GForce9800GT - nv196.21 - WinXP Sp3

zBrush4R2 - Silo2Pro - Unwrap3DPro - Gile - MaPZone2.5

 

adv_banner-april2012_720x150_tex01.png

 

Xxploration FPS in progress ...

Link to comment
Share on other sites

Since it's a light, you'll probably need update() instead of draw() because draw() will only rotate the light when the light itself is being rendered. This will mean that it's not casting shadows and such when off screen.

(I haven't tested this though)

desktop: Quad core Q6600 + 4GB + ATI HD4890 + XP

laptop: Dual core T6400 + 4 GB + NVidia 9600M GT + Vista 32

Link to comment
Share on other sites

I've added a new zip. Can you test it out?

 

This works when I run it after setting the speed property to 1.0 then 'apply' but the angle must be out because only 60% of the arc gets lit.

AMD Athlon x2 7750 2.7ghz, 6gb ddr2 ram, Galaxy9800GT 1gig ddr2 video card, Windows 7,64.

Link to comment
Share on other sites

Since it's a light, you'll probably need update() instead of draw() because draw() will only rotate the light when the light itself is being rendered. This will mean that it's not casting shadows and such when off screen.

(I haven't tested this though)

Yes I thought about that too. I tried that out but it doesn't seem to be doing anything different. The light and shadow gets rendered with both Update as well as Draw, even when the light entity is ofscreen.

 

 

This works when I run it after setting the speed property to 1.0 then 'apply' but the angle must be out because only 60% of the arc gets lit.

Yes, it bothers me that the rotation only starts after pressing 'apply'. When you load from a save where the light was turning, then the light is still rotating correctly.

But what do you mean with 'the angle must be out'?

 

sometimes icons are completely black, do you guys have this problem to? Here is a movie

http://visualknights.com/rotating%20light/lights.mp4

Link to comment
Share on other sites

Fixed it.. I rotated the light by 90 degrees in the 'General' area of the Properties. It now displays on the terrain in a full rotation. Not sure what I would use this for but it's nice to have it anyway. Thanks for writing it.

AMD Athlon x2 7750 2.7ghz, 6gb ddr2 ram, Galaxy9800GT 1gig ddr2 video card, Windows 7,64.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...