Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 009: "BACK TO BASICS: Flickering light"

CgTalk Maxscript Challenge 009: “BACK TO BASICS: Flickering light”

DESCRIPTION: Create a tool that makes a light flicker like a faulty fluorescent tube. Create animation keys for the flickering.

              INTERMEDIATE SCRIPTERS: Provide options for light delay (as in how long the light stays on or off for when not flickering), randomness or periodic flickers (like a strobe), and colour.

        ADVANCED SCRIPTERS: Make the tool create an actual fluorescent tube light object, embedded with a standard light.  Try using shaders to set up the light instead.
    
                 RULES:  

[ul]
[li]Code from scratch. Try not to use pre-exisitng functions or plugins.[/li][li]Show your script references, if any (eg. Looking at another script to assist you).[/li][li]You are encouraged to ask for help where needed, but try to do it on your own. The maxscript reference is an invaluable resource.[/li][li]Post your final script inside [/li]“`
tags (located on your posting toolbar).
[li]Post all code into THIS thread.[/li][li]Post the max version you coded in, plus any maxscript extensions you used. (Thanks galagast!)[/li][li]Try to finish the challenge in a week. There is no definite time limit. [/li][/ul] NOTES: After much deliberation, I’ve pulled the challenges down a notch. I’ll start making more simplified assignments that can be easily completed in a week.

11 Replies

This sounded fun so I took a quick stab at it. There is no UI or anything yet and some of the flicker timing needs ajusted. Just select a light and execute this code. By the way every time I try to pose code in this forum it will randomly remove spaces from the script sometimes. Am I doing something wrong?

RyanT
Pipeworks Software
Foundation 9

 
[size=1]lightNode = $
 
state = OFF
 
strength = 1
 
distanceL = 25
 
distanceH = 65
 
fluxL = .2
 
fluxH = 3
 
durationL = 3
 
durationH = 10
 
startT = 0
 
endT = 200
 
animate on
 
(
 
if state == off then
 
(at time startT (lightNode.multiplier = 0))
 
else
 
(at time startT (lightNode.multiplier = 1))
 
 
 
 
 
while startT < endT do
 
(
 
startT = startT + (random distanceL distanceH)
 
if startT < endT do
 
(
 
flickerS = startT
 
flickerE = startT + (random durationL durationH)
 
 
 
 
 
if state == off then 
 
(at time flickerS (lightNode.multiplier = 0))
 
else 
 
(at time flickerS (lightNode.multiplier = 1)) 
 
 
 
 
 
while flickerS < flickerE do
 
(
 
flickerS = flickerS + 1
 
at time flickerS
 
(
 
lowVal = (strength * fluxL)
 
highVal = (strength * fluxH)
 
 
 
 
 
lightNode.multiplier = (random lowVal highVal)
 
)
 
)
 
if state == off then
 
(at time flickerE (lightNode.multiplier = 0))
 
else 
 
(at time flickerE (lightNode.multiplier = 1)) 
 
)
 
)
 
)
 

[/size]

Here is a revision of the last script now with a UI.

-RyanT

 
rollout flicker_light "Flicker Light"
 
(
 
fn animate_light lightNode =
 
(
 
--Get Settings
 
state = flicker_light.light_state.state
 
strength = flicker_light.strength.value
 
distanceL = flicker_light.flickDistL.value
 
distanceH = flicker_light.flickDistH.value
 
fluxL = flicker_light.flickFluxL.value
 
fluxH = flicker_light.flickFluxH.value
 
durationL = flicker_light.flickDurL.value
 
durationH = flicker_light.flickDurH.value
 
durDistanceL = flicker_light.flickSpreadL.value
 
durDistanceH = flicker_light.flickSpreadH.value
 
startT = flicker_light.timeL.value
 
endT = flicker_light.timeH.value
 
 
 
animate on
 
(
 
case state of
 
(
 
1:(at time startT (lightNode.multiplier = 0))
 
2:(at time startT (lightNode.multiplier = 1))
 
3:(at time startT (lightNode.multiplier = (random 0 1)))
 
)
 
 
 
while startT < endT do
 
(
 
startT = startT + (random distanceL distanceH)
 
if startT < endT do
 
(
 
flickerS = startT
 
flickerE = startT + (random durationL durationH)
 
 
 
case state of
 
( 
 
1:(at time flickerS (lightNode.multiplier = 0))
 
2:(at time flickerS (lightNode.multiplier = 1))
 
3:(at time flickerS (lightNode.multiplier = (random 0 1)))
 
) 
 
 
 
while flickerS < flickerE do
 
(
 
flickerS = flickerS + (random durDistanceL durDistanceH)
 
if flickerS < flickerE do
 
(
 
at time flickerS
 
(
 
lowVal = (strength * fluxL)
 
highVal = (strength * fluxH)
 
 
 
lightNode.multiplier = (random lowVal highVal)
 
)
 
)
 
)
 
case state of
 
( 
 
1:(at time flickerE (lightNode.multiplier = 0)) 
 
2:(at time flickerE (lightNode.multiplier = 1))
 
3:(at time flickerE (lightNode.multiplier = (random 0 1))) 
 
)
 
)
 
)
 
)
 
) -- End animate_light FN
 

 
--UI Settings
 
pickbutton chooseNode "Pick Light" width:180 height:20
 
 
 
label time_lbl "Start/End Time:" align:#left across:3
 
spinner timeL "" range:[0,100000,0] type:#integer fieldWidth:35 align:#right
 
spinner timeH "" range:[0,100000,100] type:#integer fieldWidth:35 align:#right
 
 
 
label state_lbl "Light remains:" align:#left
 
radiobuttons light_state "" labels:#("OFF","ON","BOTH") default:1 align:#left
 
 
 
label strength_lbl "Multiplier Strength:" across:2 align:#left
 
spinner strength "" range:[.1,100,1] type:#float fieldWidth:35 align:#right
 
 
 
label flickDist_lbl "Flicker Distance:" align:#left across:3
 
spinner flickDistL "" range:[1,1000,25] type:#integer fieldWidth:35 align:#right
 
spinner flickDistH "" range:[1,1000,65] type:#integer fieldWidth:35 align:#right
 
 
 
label flickFlux_lbl "Flicker Noise:" align:#left across:3 
 
spinner flickFluxL "" range:[.1,100,.2] type:#float fieldWidth:35 align:#right
 
spinner flickFluxH "" range:[.1,100,3] type:#float fieldWidth:35 align:#right
 
 
 
label flickDur_lbl "Flicker Duration:" align:#left across:3 
 
spinner flickDurL "" range:[1,500,6] type:#integer fieldWidth:35 align:#right
 
spinner flickDurH "" range:[1,500,15] type:#integer fieldWidth:35 align:#right
 
 
 
label flickSpread_lbl "Flicker Spread:" align:#left across:3
 
spinner flickSpreadL "" range:[1,500,1] type:#integer fieldWidth:35 align:#right
 
spinner flickSpreadH "" range:[1,500,2] type:#integer fieldWidth:35 align:#right
 
 
 
button execute "Make Animation" width:180 height:20
 
 
 
on flicker_light open do
 
(
 
timeL.value = animationrange.start
 
timeH.value = animationrange.end
 
)
 
 
 
on chooseNode picked node do (chooseNode.text = node.name)
 
 
 
on execute pressed do (animate_light chooseNode.object)
 
 
 
) -- End flicker_light rollout
 
createDialog flicker_light width:210 height:230
 

Just tried it out. Nice work! I like the additional options you threw in.

Nice script.

The web board modifies lines that atre more than 50 characters long. strange but true.

I added a off color and on color to this script, it blends between them based on the multiplier. You also dont need to pick the light anymore I just have it run on anything that is a light in the selection.

-RyanT

 
rollout flicker_light "Flicker Light"
 
(
 
fn lightState state frame lightNode colorL colorH =
 
(
 
case state of
 
(
 
1:(at time frame (lightNode.multiplier = 0;lightNode.color = colorL))
 
2:(at time frame (lightNode.multiplier = 1;lightNode.color = colorH))
 
3:(
 
at time frame 
 
(
 
getVal = (random 0 1)
 
lightNode.multiplier = getVal
 
if getVal == 0 then (lightNode.color = colorL)
 
else (lightNode.color = colorH)
 
)
 
)
 
)
 
)
 
fn animate_light lightNode =
 
(
 
--Get Settings
 
state = flicker_light.light_state.state
 
colorL = flicker_light.colorL.color
 
colorH = flicker_light.colorH.color
 
strength = flicker_light.strength.value
 
distanceL = flicker_light.flickDistL.value
 
distanceH = flicker_light.flickDistH.value
 
fluxL = flicker_light.flickFluxL.value
 
fluxH = flicker_light.flickFluxH.value
 
durationL = flicker_light.flickDurL.value
 
durationH = flicker_light.flickDurH.value
 
durDistanceL = flicker_light.flickSpreadL.value
 
durDistanceH = flicker_light.flickSpreadH.value
 
startT = flicker_light.timeL.value
 
endT = flicker_light.timeH.value
 
 
 
animate on
 
(
 
lightState state startT lightNode colorL colorH
 
 
 
while startT < endT do
 
(
 
startT = startT + (random distanceL distanceH)
 
if startT < endT do
 
(
 
flickerS = startT
 
flickerE = startT + (random durationL durationH)
 
 
 
lightState state flickerS lightNode colorL colorH 
 
 
 
while flickerS < flickerE do
 
(
 
flickerS = flickerS + (random durDistanceL durDistanceH)
 
if flickerS < flickerE do
 
(
 
at time flickerS
 
(
 
lowVal = (strength * fluxL)
 
highVal = (strength * fluxH)
 
 
 
randVal = (random lowVal highVal)
 
percentVal = randVal/fluxH
 
 
 
cR = colorL.r + (colorH.r - colorL.r) * percentVal
 
cG = colorL.g + (colorH.g - colorL.g) * percentVal
 
cB = colorL.b + (colorH.b - colorL.b) * percentVal
 
 
 
lightNode.multiplier = randVal
 
lightNode.color = [cR,cG,cB]
 
)
 
)
 
)
 
lightState state flickerE lightNode colorL colorH
 
)
 
)
 
)
 
) -- End animate_light FN
 

 
--UI Settings
 
label time_lbl "Start/End Time:" align:#left across:3
 
spinner timeL "" range:[0,100000,0] type:#integer fieldWidth:35 align:#right
 
spinner timeH "" range:[0,100000,100] type:#integer fieldWidth:35
 
 
 
label state_lbl "Light remains:" align:#left
 
radiobuttons light_state "" labels:#("Off","On","Random") default:1 align:#left
 
 
 
colorpicker colorL "Off/On Colors: " fieldWidth:40 height:15 color:[105,105,105] align:#left across:2
 
colorpicker colorH "" fieldWidth:40 height:15 color:[236,230,213] align:#right
 
 
 
label strength_lbl "Multiplier Strength:" across:2 align:#left
 
spinner strength "" range:[.1,100,1] type:#float fieldWidth:35 align:#right
 
 
 
label flickDist_lbl "Flicker Distance:" align:#left across:3
 
spinner flickDistL "" range:[1,1000,25] type:#integer fieldWidth:35 align:#right
 
spinner flickDistH "" range:[1,1000,65] type:#integer fieldWidth:35 align:#right
 
 
 
label flickFlux_lbl "Flicker Noise:" align:#left across:3 
 
spinner flickFluxL "" range:[.1,100,.2] type:#float fieldWidth:35 align:#right
 
spinner flickFluxH "" range:[.1,100,3] type:#float fieldWidth:35 align:#right
 
 
 
label flickDur_lbl "Flicker Duration:" align:#left across:3 
 
spinner flickDurL "" range:[1,500,6] type:#integer fieldWidth:35 align:#right
 
spinner flickDurH "" range:[1,500,15] type:#integer fieldWidth:35 align:#right
 
 
 
label flickSpread_lbl "Flicker Spread:" align:#left across:3
 
spinner flickSpreadL "" range:[1,500,1] type:#integer fieldWidth:35 align:#right
 
spinner flickSpreadH "" range:[1,500,2] type:#integer fieldWidth:35 align:#right
 
 
 
button execute "Make Animation" width:180 height:20
 
 
 
on flicker_light open do
 
(
 
timeL.value = animationrange.start
 
timeH.value = animationrange.end
 
)
 
 
 
on chooseNode picked node do (chooseNode.text = node.name)
 
 
 
on execute pressed do 
 
(
 
for obj in selection do
 
(if (superclassof obj) == light then (animate_light obj)else(print (obj.name + ": Is not a light!")))
 
)
 
 
 
) -- End flicker_light rollout
 
createDialog flicker_light width:210 height:220
 

I finally found some free time and decided to take part in the challenge. I went a slightly different direction where a mesh is turned into a flickering light object.

 Be kind I haven't had a chance to script in max for to many months.
------------------------------------------------------------------------
   -- coded by: Thomas Blue
   -- contact@: blue@kickass3d.com
   -- v1.0 born on: 1 Oct 05
   -- written and tested on 3dsmax 7.5, untested on others but should work
   -- CgTalk Maxscript Challenge 009: "BACK TO BASICS: Flickering light"
   --  http://forums.cgsociety.org/showthread.php?t=280983 
   ------------------------------------------------------------------------
   
   try(destroyDialog flickerGeoLightMainRollout)catch()
   
   rollout flickerGeoLightMainRollout "Flickering Geo Light v1.0" width:260 height:465
   (
   	fn pickFilter node = superclassof node == GeometryClass
   	local geoLight = undefined
   	
   	pickbutton geoPBTN "Pick Geo for Light" pos:[5,5] width:230 height:20 filter:pickFilter
 	button selectGeoBTN "S" pos:[235,5] width:20 height:20 enabled:false toolTip:"Select geo to use for light"
   	GroupBox flickerGRP "Flicker Properties" pos:[5,27] width:250 height:196
   	GroupBox strobeGRP "Strobe" pos:[10,39] width:240 height:59
 	spinner frequencySPN "Frequency (frames): " pos:[98,53] width:100 height:16 range:[10,50000,30] type:#integer scale:1 
 	spinner roughnessSPN "Roughness: " pos:[114,74] width:84 height:16 range:[0,100,0] type:#integer scale:1 
   	GroupBox fadeGRP "Fade" pos:[10,101] width:240 height:42
 	spinner fadeInSPN "In (frames): " pos:[52,117] width:70 height:16 range:[0,100,3] type:#integer scale:1 
 	spinner fadeOutSPN "Out (frames): " pos:[172,117] width:70 height:16 range:[0,100,1] type:#integer scale:1 
   	GroupBox presetsGRP "Presets" pos:[10,147] width:240 height:70
   	button preset01BTN "Strobe - 1sec" pos:[17,163] width:110 height:20
   	button preset02BTN "Strobe - 1sec - Dirty" pos:[16,188] width:110 height:20
   	button preset03BTN "Totaly Random" pos:[132,163] width:110 height:20
   	button preset04BTN "No Flicker" pos:[132,188] width:110 height:20
   	GroupBox lightGRP "Light Properties" pos:[5,225] width:250 height:164
 	spinner intensitySPN "Intensity: " pos:[46,242] width:90 height:16 range:[0,20000,7100] type:#float scale:0.1
   	colorPicker lightColorCP "Color: " pos:[149,241] width:80 height:20 color:(color 240 255 255)
   	label decayLBL "Light Decay Type:" pos:[32,270]
 	dropDownList decayDDL "" pos:[123,266] width:100 height:40 items:#("None", "Inverse", "Inverse Square") selection:3
 	checkbox shadowsCBX "Shadow Map Shadows	 Size:" pos:[19,295] width:170 height:16 checked:true
 	dropDownList shadowMapSizeDDL "" pos:[193,292] width:50 height:20 items:#("32", "64", "128", "256", "512", "1024", "2048") selection:2
   	GroupBox presets2GRP "Presets" pos:[10,313] width:240 height:70
   	button preset05BTN "Warm" pos:[17,330] width:110 height:20
   	button preset06BTN "White" pos:[16,355] width:110 height:20
   	button preset07BTN "Cool" pos:[132,330] width:110 height:20
   	button preset08BTN "Default" pos:[132,355] width:110 height:20
   	checkbox materialCBX "Assign Material to Geo Light" pos:[51,394] width:163 height:16 checked:true
   	button executeBTN "Create geo light" pos:[5,416] width:230 height:20 enabled:false
   	button selectLightsBTN "S" pos:[235,416] width:20 height:20 enabled:false toolTip:"Select lights"
   	progressBar lightGenPB "ProgressBar" pos:[5,440] width:250 height:20 color:[255,192,0]
   	on geoPBTN picked node do
   	(
   		geoPBTN.text = node.name
   		executeBTN.enabled = true
   		selectGeoBTN.enabled = true
   		selectLightsBTN.enabled = true
   		geoLight = node
   		lightGenPB.value = 0
   	)
   	on selectGeoBTN pressed do
   	(
   		try(select geoLight)catch()
   	)
   	on preset01BTN pressed do
   	(
   		frequencySPN.value = 30
   		roughnessSPN.value = 0
   		fadeInSPN.value = 3
   		fadeOutSPN.value = 1
   	)
   	on preset02BTN pressed do
   	(
   		frequencySPN.value = 30
   		roughnessSPN.value = 10
   		fadeInSPN.value = 3
   		fadeOutSPN.value = 0
   	)
   	on preset03BTN pressed do
   	(
   		frequencySPN.value = 50000
   		roughnessSPN.value = 75
   		fadeInSPN.value = 1
   		fadeOutSPN.value = 0
   	)
   	on preset04BTN pressed do
   	(
   		frequencySPN.value = 50000
   		roughnessSPN.value = 0
   		fadeInSPN.value = 0
   		fadeOutSPN.value = 0
   	)
   	on preset05BTN pressed do
   	(
   		lightColorCP.color = (color 255 220 175)
   	)
   	on preset06BTN pressed do
   	(
   		lightColorCP.color = (color 255 255 255)
   	)
   	on preset07BTN pressed do
   	(
   		lightColorCP.color = (color 175 220 255)
   	)
   	on preset08BTN pressed do
   	(
   		intensitySPN.value = 7100
   		lightColorCP.color = (color 240 255 255)
   		decayDDL.selection = 3
   		shadowsCBX.checked = true
   		shadowMapSizeDDL.selection = 2
   	)
   	on executeBTN pressed do
   	(
   		lightGenPB.value = 0
   		converttomesh geoLight
   		lightColor = lightColorCP.color
   		if materialCBX.checked == true then
   		(
   			lightMaterialName = geoLight.name + "_lightMaterial"
 			lightMaterial = raytraceMaterial ambient:lightColor diffuse:lightColor \
 		 	Specular_Level:80 glossiness:55 Luminosity_Color_On:off twoSided:true \
 				Self_Illum_Amount:100 name:lightMaterialName
   			lightMaterial.ReflectionMap = falloff type:2
   			geoLight.material = lightMaterial
   		)
   		for i = 1 to geoLight.numVerts do
   		(
   			if i == 1 then
   			(
 				lightName = geoLight.name + "_fluorLight"
 		 	fluorLightIntensity = (intensitySPN.value/geoLight.numVerts)
  			 fluorLight = Omnilight name:lightName rgb:lightColor \
 		 		excludeList:#(geoLight) inclExclType:3 \
 		 		shadowColor:(color 0 0 0) multiplier:fluorLightIntensity \
 		 		decayRadius:1 attenDecay:(decayDDL.selection) shadowMultiplier:1 \
 		 	 mapsize:(shadowMapSizeDDL.selected as integer) pos:(getVert geoLight i) \
 		 		castShadows:(shadowsCBX.state) isSelected:true
   				fluorLight.parent = geoLight
   				frequency = frequencySPN.value
   				roughness = roughnessSPN.value
   				fadeIn = fadeInSPN.value
   				fadeOut = fadeOutSPN.value
 		 	animationDuration = ((animationRange.end - animationRange.start) as integer)/160 + 1
 		 	animationCycles = (animationDuration/frequency) as integer
   				if roughness != 0 then
   				(
 		 		frameTrack = animationRange.start - 1
 		 		for j = animationRange.start to animationRange.end do
   					(
 		 			if j > frameTrack then
 						(
 		 		 	frameRough = random 0 100
 		 		 	if frameRough <= roughness then
  					  (
 		 		 		dimmerStrengh = random 0 99
 		 		 		if materialCBX.checked == true then
 		 		 		(
 		 		 			at time j animate on lightMaterial.Self_Illum_Amount = 100
 		 		 			at time (j + fadeOut + 1) animate on lightMaterial.Self_Illum_Amount = dimmerStrengh
 		 		 			at time (j + fadeOut + 1 + fadeIn + 1) animate on lightMaterial.Self_Illum_Amount = 100
 		 		 		)
 		 		 		at time j animate on fluorLight.multiplier = fluorLightIntensity
 		 		 		at time (j + fadeOut + 1) animate on fluorLight.multiplier = dimmerStrengh
 		 		 		at time (j + fadeOut + 1 + fadeIn + 1) animate on fluorLight.multiplier = fluorLightIntensity
 		 		 		frameTrack = (j + fadeOut + 1 + fadeIn + 1)
  					  )
 						)
   					)
   				)
 				for j = 1 to animationCycles do
   				(
 		 		preFadeTime = (animationRange.start + (frequency * j) - fadeOut - 1)
 		 		fadeTime = (animationRange.start + (frequency * j))
 		 		postFadeTime = (animationRange.start + (frequency * j) + fadeIn + 1)
 		 		if materialCBX.checked == true then
   					(
 		 			at time preFadeTime animate on lightMaterial.Self_Illum_Amount = 100
 		 			at time fadeTime animate on lightMaterial.Self_Illum_Amount = 0
 		 			at time postFadeTime animate on lightMaterial.Self_Illum_Amount = 100
   					)
 		 		at time preFadeTime animate on fluorLight.multiplier = fluorLightIntensity
 		 		at time fadeTime animate on fluorLight.multiplier = 0
 		 		at time postFadeTime animate on fluorLight.multiplier = fluorLightIntensity
   				)
   			)
   			else
   			(
 				fluorLightInstance = instance $
   				$.pos = (getVert geoLight i)
   			)
   			lightGenPB.value = 100*i/geoLight.numVerts
   		)
   	)
   	on selectLightsBTN pressed do
   	(
   		clearSelection()
   		try(select geoLight)catch()
   		try(max select child)catch()
   		for i in selection do
   		(
   			if classof i != Omnilight then deselect i
   		)
   	)
   )
   
   createDialog flickerGeoLightMainRollout

OK so I added in alot functionality to my script over the weekend. I should probably include a help pop up soon because I imagin the tool could get confusing. Anyways, there are a few ways to use it. 1. Select a light change any options you want then hit execute. 2. Select a mesh, then a pop up will show the materials on the mesh. Select any materials you want to affect in the pop up window. This way if you have something textured with materials you dont want to illuminate they wont. You have two ways to set up light creation as well. Either auto create lights or use custom lights. If you select custom you can select lights already in the scene and have them be the flickering light for the mesh. If you choose auto it will create three lights at the angle of the mesh plus more lights between those based on how many lights are set in the extra lights option. When you select the mesh it figures out what the longest length of the mesh is and automaticly selects that option for you. You can change it if it makes a bad choice. I also added undo because when I was testing it was becoming frustrating to not have it. I have a few more ideas but I probably already went overboard.

RyanT
Pipeworks Software
Foundation 9

 
rollout flicker_light "Flicker Light"
(
 local affectedMats = #()
 local affectedLights = #()
 local mats = #()
 local matDialog
 local state,flux,colorL,colorH,Lstrength
 
 fn returnMats obj type =
 (
  getMats = #()
  if obj.material != undefined then
  (
   if (classof obj.material) == Multimaterial then
   (
	for mat in obj.material do 
	(
	 if classof mat != Multimaterial then (if type == "node" then(append getMats mat)else(append getMats mat.name))
	 else (for mult in mat do (if type == "node" then(append getMats mult)else(append getMats mult.name)))
	)
   )
   else (if type == "node" then(append getMats obj.material)else(append getMats obj.material.name))
  )
  else(DestroyDialog matDialog;messagebox "No material applied!")
  return getMats
 ) -- End returnMats FN
 fn setupMesh obj =
 (
  getAngle = obj.max - obj.min
  if getAngle.x > getAngle.y and getAngle.x > getAngle.z do (flicker_light.light_angle.state = 1)
  if getAngle.y > getAngle.x and getAngle.y > getAngle.z do (flicker_light.light_angle.state = 2)
  if getAngle.z > getAngle.x and getAngle.z > getAngle.y do (flicker_light.light_angle.state = 3)
  
  rollout matDialog "Materials"
  (
   MultiListBox matList "Select Material(s) to affect:" height:12
   button okBtn "Accept" width:180 height:20
   
   on okBtn pressed do
   (
	affectedMats = matList.selection
	DestroyDialog matDialog
   )
  )
  createDialog matDialog width:200 height:220
  
  getMats = returnMats obj "String"
  matDialog.matList.items = getMats
 ) -- End setupMesh FN
 fn selectedMats obj =
 (
  getMats = returnMats obj "node"
  selMats = #()
  for num in affectedMats do (append selMats getMats[num])
  return selMats
 ) -- End selectedMats FN
 fn lightState frame lightNode =
 (
  surgeL = (random (Lstrength*.2) (Lstrength*.6))
  surgeH = (random (Lstrength*.7) (Lstrength*1))
  case state of
  (
   1:(
	at time frame 
	(
	 for light in lightNode do
	 (
	  light.multiplier = Lstrength*surgeL
	  light.color = colorL
	 )
	 for mat in mats do (mat.selfIllumAmount = 100*(Lstrength*surgeL))
	)
   )
   2:(
	at time frame 
	(
	 for light in lightNode do
	 (
	  light.multiplier = Lstrength*surgeH
	  light.color = colorH
	 )
	 for mat in mats do (mat.selfIllumAmount = 100*(Lstrength*surgeH))
	)
   )
   3:(
	at time frame 
	(
	 getVal = (random 0 Lstrength)
	 percentVal = getVal/Lstrength
	 for mat in mats do (mat.selfIllumAmount = 100*percentVal)
	 for light in lightNode do
	 (
	  lightNode.multiplier = getVal
	  if getVal == 0 then (lightNode.color = colorL)
	  else (lightNode.color = colorH)
	 )
	)
   )
  )
 ) -- End lightState FN
 fn animate_light mesh lightNode =
 (
  --Get Settings
  if mesh != undefined do (mats = selectedMats mesh)
  state = flicker_light.light_state.state
  colorL = flicker_light.pickColorL.color
  colorH = flicker_light.pickColorH.color
  Lstrength = flicker_light.strength.value
  distanceL = flicker_light.flickDistL.value
  distanceH = flicker_light.flickDistH.value
  fluxL = flicker_light.flickFluxL.value
  fluxH = flicker_light.flickFluxH.value
  flux = fluxH - fluxL
  durationL = flicker_light.flickDurL.value
  durationH = flicker_light.flickDurH.value
  durDistanceL = flicker_light.flickSpreadL.value
  durDistanceH = flicker_light.flickSpreadH.value
  startT = flicker_light.timeL.value
  endT = flicker_light.timeH.value
  flickerE = 0
  surge = flicker_light.flickSurge.value
  
  animate on
  (
   lightState startT lightNode
   
   while startT < endT do
   (
	startT = startT + (random distanceL distanceH) -- Time flicker starts
	
	if startT < endT do
	(
	 for x = 1 to surge do
	 (
	  randSurge = (random flickerE startT)
	  lightState randSurge lightNode
	 )
	
	 flickerS = startT
	 flickerE = startT + (random durationL durationH)
	 
	 lightState flickerS lightNode
	 
	 while flickerS < flickerE do
	 (
	  flickerS = flickerS + (random durDistanceL durDistanceH)
	  if flickerS < flickerE do
	  (
	   at time flickerS
	   (
		lowVal = (Lstrength * fluxL)
		highVal = (Lstrength * fluxH)
		
		randVal = (random lowVal highVal)
		percentVal = randVal/flux
		
		cR = colorL.r + (colorH.r - colorL.r) * percentVal
		cG = colorL.g + (colorH.g - colorL.g) * percentVal
		cB = colorL.b + (colorH.b - colorL.b) * percentVal
		
		for light in lightNode do (light.multiplier = randVal)
		lightNode.color = [cR,cG,cB]
		for mat in mats do (mat.selfIllumAmount = 100*percentVal)
	   )
	  )
	 )
	 lightState flickerE lightNode
	)
   )
  )
 ) -- End animate_light FN
 
 fn executeSetup =
 (
  mesh = flicker_light.chooseNode.object
  
  if mesh != undefined then
  (
   lights = #()
   
   if flicker_light.createOpt.state == 1 then
   (
	if flicker_light.light_angle.state == 1 do
	(
	 center = mesh.center
	 min = [mesh.min.x,mesh.center.y,mesh.center.z]
	 max = [mesh.max.x,mesh.center.y,mesh.center.z]
	)
	 
	if flicker_light.light_angle.state == 2 do
	(
	 center = mesh.center
	 min = [mesh.center.x,mesh.min.y,mesh.center.z]
	 max = [mesh.center.x,mesh.max.y,mesh.center.z]
	)
	
	if flicker_light.light_angle.state == 3 do
	(
	 center = mesh.center
	 min = [mesh.center.x,mesh.center.y,mesh.min.z]
	 max = [mesh.center.x,mesh.center.y,mesh.max.z]
	)
   
	lightCent = Omnilight pos:center
	lightMin = Omnilight pos:min
	lightMax = Omnilight pos:max
	
	append lights lightCent
	append lights lightMin
	append lights lightMax
   
	case flicker_light.light_angle.state of
	(
	 1:(
	  val = flicker_light.extraLights.value+1
	  percent = 1.00/val
	  for x = 1 to (val-1)do
	  (
	   newPos = min.x + (center.x - min.x)*percent
	   newLight = Omnilight pos:[newPos,center.y,center.z]
	   append lights newLight
	   
	   newPos = max.x + (center.x - max.x)*percent
	   newLight = Omnilight pos:[newPos,center.y,center.z]
	   append lights newLight
	   percent = percent + percent
	  )
	 )
	 2:(
	  val = flicker_light.extraLights.value+1
	  percent = 1.00/val
	  for x = 1 to (val-1)do
	  (
	   newPos = min.y + (center.y - min.y)*percent
	   newLight = Omnilight pos:[center.x,newPos,center.z]
	   append lights newLight
	   
	   newPos = max.y + (center.y - max.y)*percent
	   newLight = Omnilight pos:[center.x,newPos,center.z]
	   append lights newLight
	   percent = percent + percent
	  )
	 )
 
	 3:(
	  val = flicker_light.extraLights.value+1
	  percent = 1.00/val
	  for x = 1 to (val-1)do
	  (
	   newPos = min.z + (center.z - min.z)*percent
	   newLight = Omnilight pos:[center.x,center.y,newPos]
	   append lights newLight
	   
	   newPos = max.z + (center.z - max.z)*percent
	   newLight = Omnilight pos:[center.x,center.y,newPos]
	   append lights newLight
	   percent = percent + percent
	  )
	 )
	)
   )
   else (for x in affectedLights do (append lights x))
   
   for x in lights do (x.name = uniqueName "Flicker_Omni")
 
   list = #()
   append list mesh
   
   for x in lights do (x.excludeList = list)
   animate_light mesh lights
   flicker_light.chooseNode.object = undefined
   flicker_light.chooseNode.text = "Select Mesh"
  )
  else
  (
   lights = #()
   for obj in selection do
   (if (superclassof obj) == light then (append lights obj)) 
   animate_light undefined lights
  )
 ) -- End executeSetup FN
 
 --UI Settings
 pickbutton chooseNode "Select Mesh" width:192 height:20 align:#left
 
 label createOpt_lbl "Create Lights:" width:70 across:2 align:#left
 radiobuttons createOpt "" labels:#("Auto","Custom") width:115 default:1 columns:3 align:#right
 
 button chooseLights "Select Light(s)" width:192 height:20 enabled:false align:#left
 
 label time_lbl "Start/End Time:" align:#left across:3
 spinner timeL "" range:[0,100000,0] type:#integer fieldWidth:35 align:#right
 spinner timeH "" range:[0,100000,100] type:#integer fieldWidth:35
 
 label extraLights_lbl "Extra Lights:" align:#left across:3
 label blank_1 ""
 spinner extraLights "" range:[0,50,2] type:#integer fieldWidth:35 align:#right 
 
 label angle_lbl "Mesh Angle:" align:#left across:2
 radiobuttons light_angle "" labels:#("X","Y","Z") default:1 columns:3 align:#right
 
 label state_lbl "Light State:" align:#left
 radiobuttons light_state "" labels:#("Off","On","Random") default:1 align:#left
 
 label color_lbl "Off/On Colors:  " across:3 align:#left
 colorpicker pickColorL "" fieldWidth:40 height:15 color:[131,143,158] align:#right
 colorpicker pickColorH "" fieldWidth:40 height:15 color:[236,230,213] align:#right
 
 label strength_lbl "Multiplier Strength:" across:3 align:#left
 label blank_2 ""
 spinner strength "" range:[.1,100,.7] type:#float fieldWidth:35 align:#right
 
 label flickSurge_lbl "Distance Surges:" across:3 align:#left
 label blank_3 ""
 spinner flickSurge "" range:[0,500,3] type:#integer fieldWidth:35 align:#right
 
 label flickDist_lbl "Flicker Distance:" across:3 align:#left
 spinner flickDistL "" range:[1,1000,25] type:#integer fieldWidth:35 align:#right
 spinner flickDistH "" range:[1,1000,65] type:#integer fieldWidth:35 align:#right
 
 label flickFlux_lbl "Flicker Noise:" align:#left across:3 
 spinner flickFluxL "" range:[.1,100,.2] type:#float fieldWidth:35 align:#right
 spinner flickFluxH "" range:[.1,100,.7] type:#float fieldWidth:35 align:#right
 
 label flickDur_lbl "Flicker Duration:" align:#left across:3 
 spinner flickDurL "" range:[1,500,6] type:#integer fieldWidth:35 align:#right
 spinner flickDurH "" range:[1,500,15] type:#integer fieldWidth:35 align:#right
 
 label flickSpread_lbl "Flicker Spread:" align:#left across:3
 spinner flickSpreadL "" range:[1,500,1] type:#integer fieldWidth:35 align:#right
 spinner flickSpreadH "" range:[1,500,4] type:#integer fieldWidth:35 align:#right
 
 button execute "Animate Light" width:192 height:20 align:#left
 
 on flicker_light open do
 (
  timeL.value = animationrange.start
  timeH.value = animationrange.end
 )
 
 on createOpt changed option do
 (
  if option == 1 then 
  (
   chooseLights.enabled = false
   light_angle.enabled = true
   extraLights.enabled = true
   chooseLights.text = "Select Light(s)"
   affectedLights = #()
  )
  else 
  (
   chooseLights.enabled = true
   light_angle.enabled = false
   extraLights.enabled = false
  )
 )
 
 on chooseLights pressed do
 (
  affectedLights = #()
  for obj in selection do
  (if (superclassof obj) == light then (append affectedLights obj))
  chooseLights.text = ((affectedLights.count as string) + " - Light(s) Picked")
 )
 
 on chooseNode picked node do 
 (
  setupMesh node
  chooseNode.text = node.name
 )
 
 on execute pressed do with undo label:"Undo" on (executeSetup())
 
) -- End flicker_light rollout
createDialog flicker_light width:220 height:355
 

RyanT: I just tried your script and I have a few suggestions:

[ul]
[li]Consider wiping out the self illum keys on materials that have already been keyed one or more times instead of adding new keys ontop of the existing one, or as you can guess the the light and materials get out of sync.[/li][li]Instancing the lights so it will make it easier for an end user to make edits to the lights.[/li][li]Grouping the lights with the geo would be helpfull for scene manipulation. (I chose to link to the lights to the geo but its the same idea)[/li][/ul] Pretty cool overall though, I like it.

Hey blue,

Thanks for the suggestions. I will have to do that. I thought that having an option to wipe out the keys on the material and lights might be good. Let the user choose if they want to do it or not. Grouping them / linking them is a good idea too.

-RyanT

Page 1 / 2