Lightning generator

well here is the beginning of a lightning generator script. currently it only generates the flashes from the lightning not the lightning itself. that is still being worked on. in its current state the script is fairly basic, just modify the variables to suit your scene, no GUI (not yet, the GUI script is still buggy and i dont want to release it till its perfect) at any rate, im hoping to create a fully featured script to generate lightning, the flashes (already done), clouds, wind everything in a storm…hopefully.

there is a small test video here (200k) : http://home.iprimus.com.au/snapper63/lightning2.avi

to use it you will need a spot lamp with ray shadows on with the object name of “Emitter” minus quotes. you should track it to an empty in the middle of your scene so that the lightning always points to the scene.
also because of a bug in blender’s python api you will need to assign the generated lamp data ipo to the spot lamp.

anyways im open to ideas and requests. id love to see anything done with it.

tim


from Blender import *
import math

rnd = Mathutils.Rand

#lighting rig radius
radius = 50

#lowest point of origin
floor = 20

#heighest point of origin
ceiling = 60

#intensity variance over height range (percentage)
height_falloff = 0.5

#maximum strike intensity
max_intensity = 3

#number of frames for light to dissipate
light_fallOff = 3

#number of smaller striks after a major strike
strike_fallOff = 5

#maximum number of secondary strikes
secondaryStrike_max = 3

#intensity of secondary strikes relative to major strike (percentage)
secondaryStrike_fallOff = 0.5

#max time between secondary strikes
secondaryStrike_time = 75

#number of frames between major strikes
strike_frequency = 100

#layer that lamps are on
lightLayer = 10

#starting frame
start_frame = 0

#end frame
end_frame = 2500



height_range = ceiling - floor
frame_range = end_frame - start_frame
probability = 1 / strike_frequency

try:
	emitter = Object.Get("Emitter")
except:
	name = "Error%t|No lamp object called Emitter" 
	result = Draw.PupMenu(name)
	raise

objIpo = Ipo.New("Object","EmitObj")
lampIpo = Ipo.New("Lamp","EmitLamp")

xIpo = objIpo.addCurve("LocX")
yIpo = objIpo.addCurve("LocY")
zIpo = objIpo.addCurve("LocZ")

energyIpo = lampIpo.addCurve("Energ")

number_majorStrikes = int(frame_range / strike_frequency)

for strike in range(number_majorStrikes):
	frame = int(rnd() * frame_range + start_frame)
	intensity = rnd() * (max_intensity * secondaryStrike_fallOff) + (max_intensity * secondaryStrike_fallOff)
	direction = int(rnd() * 2 * math.pi)
	height = rnd() * height_range + floor
	x = radius * math.cos(direction)
	y = radius * math.sin(direction)
	xIpo.addBezier((frame,x))
	yIpo.addBezier((frame,y))
	zIpo.addBezier((frame,height))
	energyIpo.addBezier((frame-1,0))
	energyIpo.addBezier((frame,intensity))
	energyIpo.addBezier((frame + light_fallOff,0))
	sec_strikes = int(rnd() * secondaryStrike_max)
	for sec in range(sec_strikes):
		sec_frame = frame + int(rnd() * secondaryStrike_time)
		intensity = rnd() * max_intensity * secondaryStrike_fallOff
		direction = int(rnd() * 2 * math.pi)
		x = radius * math.cos(direction)
		y = radius * math.sin(direction)
		height = rnd() * height_range + floor	
		xIpo.addBezier((sec_frame,x))
		yIpo.addBezier((sec_frame,y))
		zIpo.addBezier((sec_frame,height))
		energyIpo.addBezier((sec_frame-1,0))
		energyIpo.addBezier((sec_frame,intensity))
		energyIpo.addBezier((sec_frame + light_fallOff,0))
		
emitter.setIpo(objIpo)
# emitter.getData().setIpo(lampIpo) # currently a bug in blender

Redraw()

Haven’t tried the script yet, but it’s something that been missing! Thanks. Looking forward to giving it a try.