[Closed] CgTalk Maxscript Challenge 005: "Lightning Bolts"
CgTalk Maxscript Challenge 005: “Lightning Bolts” – (As suggested by JHaywood)
DESCRIPTION: Create jagged animated lightning bolts from one object to the surface of another object. You can either do this as a random automatic function, or make it an actual tool with options.
INTERMEDIATE SCRIPTERS: The bolts must light up the scene like actual lightning.
ADVANCED SCRIPTERS: Create surface scarring from the bolt with a procedural texture.
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][li]Voting will occur at the end of each ‘month’ (every 4 challenges). [/li][/ul] NOTES: A little simpler than the last one (great work by the way!), this one should prove useful! Keep on coding! Thanks for the suggestion James!
***EDIT: Fixed a small bug that generated errors half-way through the simulation
Ok…I’m not sure if this was what was expected in this challenge…but I figured I’d give it a shot anyways hehe.
Basically, this script takes to objects of any kind (that you choose), and creates an animated lightning bolt (well…more like an electric bolt) between them. All of the settings can be adjusted so that it can be any size of detail that you like (to some extent hehe).
Also, by default, the whole spline is animated…but you can change settings to affect the falloff from the end points (so areas closer to the end points are not as wavy)…or…you can lock off the ends so that the bolt of electricity is “attached” to the objects, as it moves
Btw…I apologize ahead of time for not adding comments to the code
http://www.theonlyt.com/Main/Scripts/zapper.ms
--Spline Lightning script by Tyson Ibele, 2005.
global startTime = bezier_float()
global endTime = bezier_float()
global falloffc = bezier_float()
global bdet = bezier_float()
global pdet = bezier_float()
global a1 = bezier_float()
global a2 = bezier_float()
global lock_ends
global dum1
global dum2
rollout lightn "Main Parameters"
(
pickbutton obj1 "Select Base Object" width:150
pickbutton obj2 "Select End Object" width:150
spinner start1 "Start Time: " type:#integer range:[-100000,100000,0] controller:startTime width:100
spinner end1 "End Time: " type:#integer range:[-100000,100000,100] controller:endTime width:100
button zap "Zap it!" width:70 height:30
progressbar prog color:red
progressbar prog2 color:blue
on obj1 picked obj do
(
dum1 = obj
obj1.text = dum1.name
)
on obj2 picked obj do
(
dum2 = obj
obj2.text = dum2.name
)
on zap pressed do
(
if dum1 != undefined and dum2 != undefined then
(
ltng = SplineShape()
addNewSpline ltng
addKnot ltng 1 #corner #line dum1.pos
addKnot ltng 1 #corner #line dum2.pos
ltng.pivot = ltng.center
updateShape ltng
remSlider = sliderTime
sliderTime = 0
init_pos = #()
counter = 0
prog.value = 0
prog2.value = 0
mainprog = 0
for p in (startTime.value as integer) to (endTime.value as integer) do
(
counter += 1
sliderTime += 1
prog.value = (counter/(endTime.value-startTime.value))*100
mainprog = prog.value/2
prog2.value = mainprog
proxy = SplineShape()
addNewSpline proxy
addKnot proxy 1 #corner #line dum1.pos
addKnot proxy 1 #corner #line dum2.pos
updateShape proxy
init_pos_ver = #()
for i in 1 to bdet.value do
(
numk = (numsegments proxy 1) * 2
for j in 1 to numk by 2 do
(
refineSegment proxy 1 j 0.5
)
updateShape proxy
)
for g in 1 to (numKnots proxy 1) do
(
init_pos_ver[g] = getKnotPoint proxy 1 g
)
init_pos[counter] = init_pos_ver
delete proxy
)
sliderTime = remSlider
for i in 1 to bdet.value do
(
numk = (numsegments ltng 1) * 2
for j in 1 to numk by 2 do
(
refineSegment ltng 1 j 0.5
)
updateShape ltng
)
remPos = #()
getPos = #()
ltng.wireColor = white
for p in 1 to (numKnots ltng 1) do
(
remPos[p] = getKnotPoint ltng 1 p
)
animateVertex ltng #all
counter = 0
prog.value = 0
for m in (startTime.value as integer) to (endTime.value as integer) do
(
rand1 = (random 0 600)
rand4 = (random .4 1.5) * a1.value
rand5 = (random .2 2) * a2.value
fallcount = 1
counter += 1
prog.value = (counter/(endTime.value-startTime.value))*100
mainprog = (prog.value/2)+50
prog2.value = (mainprog as integer)
for k in 1 to (numKnots ltng 1) do
(
setKnotPoint ltng 1 k remPos[k]
setKnotType ltng 1 k #corner
initial_pos = init_pos[counter][k]
if fallcount > (numKnots ltng 1)/2 then fallcount = (numKnots ltng 1)/2
if fallcount < 0 then fallcount = 0
if k <= (numKnots ltng 1)/2 then
(
falloff = (1-falloffc.value) * fallcount
if falloff < 0 then falloff = 0
if falloff > 1 then falloff = 1
fallcount += .2
)
else
(
falloff = ((1-falloffc.value) * fallcount)
if falloff < 0 then falloff = 0
if falloff > 1 then falloff = 1
fallcount -= .2
)
if lock_ends == true then
(
if k == 1 or k == (numKnots ltng 1) then falloff = 0
)
v1 = (random (1*pdet.value) (2*pdet.value))*falloff
rand2 = (((sin((k*6*rand4)+rand1))*5)*rand5)*falloff
rand3 = (((sin(k*30*rand4)))*rand5)*falloff
setKnotPoint ltng 1 k (initial_pos + [rand2, rand2, rand2])
initial_pos = getKnotPoint ltng 1 k
setKnotPoint ltng 1 k (initial_pos + [rand3, rand3, rand3])
initial_pos = getKnotPoint ltng 1 k
setKnotPoint ltng 1 k (initial_pos + (random [0,0,0] [v1,v1,v1]))
getPos[k] = getKnotPoint ltng 1 k
updateShape ltng
track = 3*(k-1)+2
key = addNewKey ltng[#Object__Editable_Spline][#master][track].controller m
key.value = getPos[k]
updateShape ltng
)
)
)
else messagebox "You must first choose 2 objects"
prog.value = 0
prog2.value = 0
)
)
rollout settings "Tweakable Settings"
(
spinner detail1 "Bolt Detail: " type:#integer range:[2,8,6] controller:bdet width:100 align:#right
spinner detail2 "Perturb Amount: " type:#integer range:[0,6,2] controller:pdet width:100 align:#right
spinner amp1 "Cycle Multiplier: " type:#float range:[0,6,2] controller:a1 width:100 align:#right
spinner amp2 "Amp Size: " type:#float range:[0,6,2] controller:a2 width:100 align:#right
spinner falloff1 "End Falloff: " type:#float range:[0,0.99 ,1] controller:falloffc width:100 align:#right
checkbox lock1 "Lock Ends" align:#right
on lock1 changed check1 do
(
lock_ends = check1
)
)
zapit=newrolloutfloater "Spline Zapper" 200 365 750 200
addrollout lightn zapit
addrollout settings zapit
startTime.value = 0
endTime.value = 100
falloffc.value = 0.5
bdet.value = 6
pdet.value = 3
a1.value = 1
a2.value = 1
dum1 = undefined
dum2 = undefined
Nice! And so dang fast!
Mine almost does the same thing, but I’m going for a lightning strike with multiple forks. That’s right, i’m actually participating this time!
Hehe…thanks erilaz…yes I was actually going to try to add in some forks myself…hopefully I’ll get to it by the end of the challenge
I guess since I suggested it, I should post an entry in this one.
I using a slightly different approach where I’m basically creating a bunch of dummies with noise controllers and binding a spline to them.
Here's how it works:
- Run the script and you'll get a floating rollout where you can define the start and end objects for the electricity bolt.
-
There’s also two spinners that control the overal “detail” of the bolt. Use a smaller number, like 2, for the main controls, and a bigger number, like 6, for the sub controls. If you unhide the dummies after clicking the “DO IT!” button, you’ll see what these spinner are really doing.
- Click the “DO IT!” button to build to bolt.
-
Select the start object and you’ll see a bunch of spinners in the modifier panel. The best way to experiment with these and see what they do is to click the play button and start changing numbers.
- Start with the “Mini Noise Control” section and go up from there to add new layers of motion.
- The “Strength” spinners control how much movement, and in which world axis, the bolt has.
- The “Frequency” spinners control how fast the movement is. Experiment with numbers like .01 to get it moving really slow.
-
The “Render” section lets you define the thickness, as well as the randomness of the thickness. You can also define the color of the bolt.
-
“End Point Pos” lets you animate the bolt shooting from the start object to the end object.
-
You can animate the start and end objects moving around and the bolt will follow.
-
All the spinners are animatable.
-
I’d like to add some forks on here too. And I’d like to add an overall visibility control so that it kind of blinks on and off randomly.
Have fun!
/*
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
Ride the Lightning
v1.0
Created: 07/05
By: James Haywood
---------------------------------------------------------------------------------------
Description:
Creates a lightning object between two points.
How it works:
A spline is created between the Start Object and the End Object, as defined by the pick
buttons. Sub Controls and Main Controls are created, with their numbers defined by the
rollout spinners. The Sub Controls are actually spline IK objects that move the spline
directly. The Main Controls are helpers that the Sub Controls are position constrained to,
and are themselves position constrained between the start and end objects. All the controls
have noise controllers on them which create the random movement.
Custom attribute controls are added to the start object which control the strength and
frequency of the various noise parameters, as well as the thickness of the render mesh
for the spline.
---------------------------------------------------------------------------------------
To do list:
- Add option for forks.
History:
v1.00 - Fully armed and operational.
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
*/
fn freezePosition obj = (
obj.pos.controller = position_list()
posCon = obj.pos.controller
posCon.available.controller = position_XYZ()
posCon.setName 1 "dontUse"
posCon.setName 2 "frozen"
posCon.setActive 2
)
-- thanks to Mike B, the math master
fn smoothpulse a b t = (
if t <= a then return 0
if t >= b then return 0
t = (t-a)/(b-a)
t = 1-((abs (t-0.5))*2)
return (t * t * (3 - 2 * t ))
)
rollout lightningGeneratorRlt "Haywood Tools" (
group "Ride the Lightning" (
pickButton pickStartBtn "Pick Start Object"
pickButton pickEndBtn "Pick End Object"
spinner numMainControlsSpnr "Main Controls #:" range:[1,100,1] type:#integer width:100 align:#right
spinner numSubControlsSpnr "Sub Controls #:" range:[1,100,1] type:#integer width:100 align:#right
)
button doItBtn "DO IT!" width:100 height:35 offset:[0,10]
on pickStartBtn picked obj do (
pickStartBtn.text = obj.name
)
on pickEndBtn picked obj do (
pickEndBtn.text = obj.name
)
on doItBtn pressed do (
if pickStartBtn.object != undefined and pickEndBtn.object != undefined then (
max modify mode
-- set animation range
animRange = animationRange
animationRange = (interval -10000 100000)
-- define controls
obj1 = pickStartBtn.object
obj2 = pickEndBtn.object
numMainControls = numMainControlsSpnr.value
numSubControls = numSubControlsSpnr.value
subControlsArr = #()
mainControlsArr= #()
uberMainControlsArr = #(obj1)
-- define variable to use for scale
splineScale = ((obj2.max.x - obj2.min.x) + (obj2.max.y - obj2.min.y) + (obj2.max.z - obj2.min.z)) / 3
-- create helper object to control length of spline from obj1 to obj2
lengthHelper = point box:off centerMarker:off axisTripod:off cross:on
lengthHelper.pos = obj2.pos
lengthHelper.size = splineScale
lengthHelper.name = (obj1.name + "_lengthHelper")
lengthHelper.wirecolor = (color 87 224 198)
-- create spline that goes from obj1 to lengthHelper
baseSpline = splineShape name:(obj1.name + "_baseSpline") pos:obj1.pos
baseSpline.wirecolor = (color 87 224 198)
addNewSpline baseSpline
addKnot baseSpline 1 #corner #line obj1.pos
addKnot baseSpline 1 #corner #line lengthHelper.pos
updateShape baseSpline
baseSpline.baseObject.renderable = true
baseSpline.displayRenderMesh = true
baseSpline.sides = 3
baseSpline.optimize = true
baseSpline.steps = 1
-- add self-illuminated material to spline
splineMat = standard()
baseSpline.material = splineMat
splineMat.ambient = baseSpline.wirecolor
splineMat.diffuse = baseSpline.wirecolor
splineMat.selfillumamount = 100
splineMat.name = uniqueName (obj1.name + "_material")
-- create mainControls
-- add normalize spline modifier and set the length so that there are enough segments for the number of mainControls needed
nsMod = normalize_spl()
addModifier baseSpline nsMod
nsMod.length = (curveLength baseSpline) / (numMainControls + 1)
-- collapse stack
collapseStack baseSpline
-- create helper objects for numMainControls
for i = 1 to numMainControls do (
p = point box:on centerMarker:off axisTripod:off cross:off
p.size = splineScale * 2
p.wirecolor = (color 87 224 198)
p.name = uniquename (obj1.name + "_mainControl")
p.pos = getKnotPoint baseSpline 1 (i + 1)
append mainControlsArr p
append uberMainControlsArr p
)
append uberMainControlsArr lengthHelper
-- create subControls
-- add normalize spline modifier and set the length so that there are enough segments for the number of subControls needed
nsMod = normalize_spl()
addModifier baseSpline nsMod
nsMod.length = (curveLength baseSpline) / (numSubControls + 1)
-- collapse stack
collapseStack baseSpline
-- add splineIK control modifier and create splineIK helpers
sIKMod = spline_ik_control()
addModifier baseSpline sIKMod
sIKMod.linkTypes = 2
sIKMod.helper_size = splineScale
sIKMod.createHelper (numKnots baseSpline 1)
subControlsArr = sIKMod.helper_list
-- rename subControls
for i in subControlsArr do (
i.name = uniquename (obj1.name + "_subControl")
i.wirecolor = (color 39 100 88)
)
-- freeze position on all objects
freezePosition baseSpline
freezePosition lengthHelper
for i in mainControlsArr do (freezePosition i)
for i in subControlsArr do (freezePosition i)
-- link objects
subControlsArr[1].parent = obj1
subControlsArr[subControlsArr.count].parent = lengthHelper
lengthHelper.parent = obj2
-- add a normalize spline modifier to the baseSpline to create many small segments (detail) in the lightning bolt
nsMod = normalize_spl()
addModifier baseSpline nsMod
nsMod.length = splineScale * .5
-- add noise modifier to baseSpline to give the detail some random movement
noiseMod = noiseModifier()
addModifier baseSpline noiseMod
noiseMod.scale = splineScale * .25
noiseMod.strength = [splineScale,splineScale,splineScale]
noiseMod.animate = on
noiseMod.frequency = 2
noiseMod.seed = random 0 1000
for i in noiseMod.phase.controller.keys do (
i.inTangentType = #linear
i.outTangentType = #linear
)
-- add position constraint to lengthHelper to control length of baseSpline from obj1 to obj2
posCon = position_constraint()
lengthHelper.position.controller.available.controller = posCon
posCon.appendTarget obj1 100
lengthHelper.position.controller.setName 3 "autoPos"
lengthHelper.position.controller.setActive 3
lengthHelper.position.controller[#weights][#Weight__autoPos].value = 0
-- add controllers to mainControls
c = mainControlsArr.count
for i = 1 to c do (
local obj = mainControlsArr[i]
-- add position constraints to mainControls to constrain them between obj1 and lengthHelper
n = ((100.0 / (c + 1)) * i)
posCon = position_constraint()
obj.position.controller.available.controller = posCon
posCon.appendTarget obj1 (100 - n)
posCon.appendTarget lengthHelper n
-- add noise controller
noiseCon = noise_position()
obj.position.controller.available.controller = noiseCon
noiseCon[#noise_strength].controller = point3_XYZ()
-- change values
noiseCon.seed = random 0 1000
noiseCon.roughness = 1
-- add positionXYZ for animating
xyzCon = position_xyz()
obj.position.controller.available.controller = xyzCon
-- set names and active controller
obj.position.controller.setName 3 "autoPos"
obj.position.controller.setName 4 "noisePos"
obj.position.controller.setName 5 "animate"
obj.position.controller.setActive 5
)
-- add controllers to subControls
mc = uberMainControlsArr.count
sc = subControlsArr.count
for j = 2 to (sc-1) do (
local obj = subControlsArr[j]
-- add position constraints to make the subControls move with the mainControls
-- got major help from Mike B on this one
posCon = position_constraint()
obj.position.controller.available.controller = posCon
for i = 1 to mc do (
range = .45
t = ( ((i as float)/(mc+1)) - ((j as float)/(sc+1)) )
w = 100.0 * (smoothpulse -range range t)
posCon.appendTarget uberMainControlsArr[i] w
)
-- add noise controller
noiseCon = noise_position()
obj.position.controller.available.controller = noiseCon
noiseCon[#noise_strength].controller = point3_XYZ()
-- change values
noiseCon.seed = random 0 1000
noiseCon.roughness = 1
-- add positionXYZ for animating
xyzCon = position_xyz()
obj.position.controller.available.controller = xyzCon
-- set names and active controller
obj.position.controller.setName 3 "autoPos"
obj.position.controller.setName 4 "noisePos"
obj.position.controller.setName 5 "animate"
obj.position.controller.setActive 5
)
-- create custom attribute controls on obj1
lightningControlsCA = attributes lightningControlsAtts (
parameters lightningControls rollout:lightningControlsRlt (
endPointPos ui:endPointPosSpnr type:#float default:1
-- Macro Noise Control
mcNoiseStrengthX ui:mcnsXSpnr type:#float
mcNoiseStrengthY ui:mcnsYSpnr type:#float
mcNoiseStrengthZ ui:mcnsZSpnr type:#float
mcNoiseStrengthXYZ ui:mcnsAllSpnr type:#float
mcFrequency ui:mcfrSpnr type:#float animatable:false default:.5
-- Main Noise Control
scNoiseStrengthX ui:scnsXSpnr type:#float
scNoiseStrengthY ui:scnsYSpnr type:#float
scNoiseStrengthZ ui:scnsZSpnr type:#float
scNoiseStrengthXYZ ui:scnsAllSpnr type:#float
scFrequency ui:scnsfrSpnr type:#float animatable:false default:.5
-- Mini Noise Control
splNoiseStrength ui:splnsSpnr type:#float
splNoiseFreq ui:splnfSpnr type:#float animatable:false default:5
splNoiseScale ui:splnsclSpnr type:#float
-- render controls
splThickness ui:splthckSpnr type:#float
splRandom ui:splrndSpnr type:#float
splStrength ui:splstrSpnr type:#float
splColor ui:splclr type:#color default:[87,224,198]
-- nodes
baseSplineID type:#integer animatable:false
mcIDHandles type:#intTab tabSizeVariable:true
scIDHandles type:#intTab tabSizeVariable:true
)
rollout lightningControlsRlt "Lighting Controls" (
spinner endPointPosSpnr "End Point Pos:" align:#right range:[0,1,1]
group "Macro Noise Control" (
spinner mcnsXSpnr "Strength X:" align:#right range:[0,100000,0]
spinner mcnsYSpnr "Strength Y:" align:#right range:[0,100000,0]
spinner mcnsZSpnr "Strength Z:" align:#right range:[0,100000,0]
spinner mcnsAllSpnr "Strength XYZ:" align:#right range:[0,100000,0]
spinner mcfrSpnr "Frequency" align:#right range:[0,100000,.5]
)
group "Main Noise Control" (
spinner scnsXSpnr "Strength X:" align:#right range:[0,100000,0]
spinner scnsYSpnr "Strength Y:" align:#right range:[0,100000,0]
spinner scnsZSpnr "Strength Z:" align:#right range:[0,100000,0]
spinner scnsAllSpnr "Strength XYZ:" align:#right range:[0,100000,0]
spinner scnsfrSpnr "Frequency" align:#right range:[0,100000,.5]
)
group "Mini Noise Control" (
spinner splnsSpnr "Strength:" align:#right range:[0,100000,0]
spinner splnfSpnr "Frequency:" align:#right range:[0,100000,5]
spinner splnsclSpnr "Scale:" align:#right range:[0,100000,0]
)
group "Render" (
spinner splthckSpnr "Thickness:" align:#right range:[0,100000,0]
spinner splrndSpnr "Randomize:" align:#right range:[0,1,0]
spinner splstrSpnr "Strength:" align:#right range:[0,100000,0] enabled:false
colorpicker splclr "Color:" align:#right
)
on lightningControlsRlt open do (
if splrndSpnr.value > 0 then splstrSpnr.enabled = true else splstrSpnr.enabled = false
)
on mcnsAllSpnr changed val do (
mcnsXSpnr.value = val
mcnsYSpnr.value = val
mcnsZSpnr.value = val
)
on mcfrSpnr changed val do (
for i in mcIDHandles do (
local obj = maxOps.getNodeByHandle i
obj.position.controller[#noisePos].frequency = val
)
)
on scnsAllSpnr changed val do (
scnsXSpnr.value = val
scnsYSpnr.value = val
scnsZSpnr.value = val
)
on scnsfrSpnr changed val do (
for i in scIDHandles do (
local obj = maxOps.getNodeByHandle i
obj.position.controller[#noisePos].frequency = val
)
)
on splnsAllSpnr changed val do (
splnsXSpnr.value = val
splnsYSpnr.value = val
splnsZSpnr.value = val
)
on splnfSpnr changed val do (
local obj = maxOps.getNodeByHandle baseSplineID
obj.modifiers[#noise].frequency = val
)
on splrndSpnr changed val do (
if val == 0 then splstrSpnr.enabled = false else splstrSpnr.enabled = true
)
)
)
-- add empty modifier to hold custom attributes
emptyMod = emptyModifier()
addModifier obj1 emptyMod
emptyMod.name = "Lighting Controls"
custAttributes.add emptyMod lightningControlsCA
-- define node handles for lightningControlsCA
emptyMod.baseSplineID = baseSpline.inode.handle
mcIDArr = for i in mainControlsArr collect i.inode.handle
scIDArr = for i = 2 to (subControlsArr.count - 1) collect subControlsArr[i].inode.handle
emptyMod.mcIDHandles = mcIDArr
emptyMod.scIDHandles = scIDArr
-- wiring
lightningControls = emptyMod.lightningControlsAtts
-- wire length control
paramWire.connect lightningControls[#endPointPos] lengthHelper.position.controller[#weights][#Weight__autoPos] "1 - endPointPos"
-- main controls
for i in mainControlsArr do (
-- length control
paramWire.connect lightningControls[#endPointPos] i.position.controller[#weights][#Weight__noisePos] "endPointPos"
-- wire Macro Noise Control
paramWire.connect lightningControls[#mcNoiseStrengthX] i.position.controller[#noisePos][#noise_strength][#x] "mcNoiseStrengthX"
paramWire.connect lightningControls[#mcNoiseStrengthY] i.position.controller[#noisePos][#noise_strength][#y] "mcNoiseStrengthY"
paramWire.connect lightningControls[#mcNoiseStrengthZ] i.position.controller[#noisePos][#noise_strength][#z] "mcNoiseStrengthZ"
)
-- sub controls
for i = 2 to (sc - 1) do (
-- length control
paramWire.connect lightningControls[#endPointPos] subControlsArr[i].position.controller[#weights][#Weight__noisePos] "endPointPos"
-- wire Macro Noise Control
paramWire.connect lightningControls[#scNoiseStrengthX] subControlsArr[i].position.controller[#noisePos][#noise_strength][#x] "scNoiseStrengthX"
paramWire.connect lightningControls[#scNoiseStrengthY] subControlsArr[i].position.controller[#noisePos][#noise_strength][#y] "scNoiseStrengthY"
paramWire.connect lightningControls[#scNoiseStrengthZ] subControlsArr[i].position.controller[#noisePos][#noise_strength][#z] "scNoiseStrengthZ"
)
-- spline noise control
paramWire.connect lightningControls[#splNoiseStrength] baseSpline.modifiers[#Noise][#strength] "[splNoiseStrength,splNoiseStrength,splNoiseStrength]"
paramWire.connect lightningControls[#splNoiseScale] baseSpline.modifiers[#Noise][#scale] "splNoiseScale"
-- spline render controls
lightningControls[#splThickness].controller = float_list()
lightningControls[#splThickness].controller.available.controller = bezier_float()
lightningControls[#splThickness].controller.available.controller = noise_float()
baseSpline.baseObject[#thickness].controller = lightningControls[#splThickness].controller
paramWire.connect lightningControls[#splRandom] lightningControls[#splThickness][#weights][#Weight__Noise_Float] "splRandom"
paramWire.connect lightningControls[#splStrength] lightningControls[#splThickness][#noise_float][#noise_strength] "splStrength"
paramWire.connect lightningControls[#splColor] baseSpline[5][#Shader_Basic_Parameters][#Diffuse_Color] "splColor"
-- hide controls
for i in subControlsArr do hide i
for i in mainControlsArr do hide i
hide lengthHelper
-- reset animation range
animationRange = animRange
)
) -- end doItBtn pressed
) -- end rollout
createDialog lightningGeneratorRlt width:150 pos:[40,80]
Great job James! Love the handles and IK work you’ve thrown into this! A really unique method! I noticed the animation range is off the charts though. A setup for wire parameters?
Here’s the first stage of mine. It works on the same method of picking two objects, but then has options for number of forked bolts off the root bolt, plus amount of jags. No animation as yet. I want to throw in an animation that actually strikes the surface, rather than a continual zap:
global boltEm
global boltSurf
fn makeBolts seedNum maxJag minJag bolts =
(
seed seedNum
rootBolt = line steps:6 thickness:1.0
convertToSplineShape rootBolt
updateShape rootBolt -- how many times do I have to update this thing???
addNewSpline rootBolt
addKnot rootBolt 1 #corner #line boltEm.pos
addKnot rootBolt 1 #corner #line boltSurf.pos
updateShape rootBolt
jags = random minJag maxJag
for i = 1 to jags do
(
segs = numSegments rootBolt 1
refineSegment rootBolt 1 (random 1 segs) (random 0.1 0.9)
)
updateShape rootBolt
kNum = numKnots rootBolt
for i = 2 to (kNum-1) do
(
kPos = getKnotPoint rootBolt 1 i
setKnotPoint rootBolt 1 i (kPos + [(random -10 10),(random -10 10),(random -10 10)])
setKnotType rootBolt 1 i #corner
)
updateShape rootBolt
-- add extra bolts!
for bIdx = 2 to bolts do
(
splineN = addNewSpline rootBolt
addKnot rootBolt bIdx #corner #line (getKnotPoint rootBolt 1 (random 1 (numKnots rootBolt 1)))
addKnot rootBolt bIdx #corner #line boltSurf.pos
updateShape rootBolt
jags = random minJag maxJag
for i = 1 to jags do
(
segs = numSegments rootBolt bIdx
refineSegment rootBolt bIdx (random 1 segs) (random 0.1 0.9)
)
updateShape rootBolt
kNum = numKnots rootBolt bIdx
for i = 2 to (kNum-1) do
(
kPos = getKnotPoint rootBolt bIdx i
setKnotPoint rootBolt bIdx i (kPos + [(random -10 10),(random -10 10),(random -10 10)])
setKnotType rootBolt bIdx i #corner
)
updateShape rootBolt
)
rootBolt.renderable = true
rootBolt.thickness = 1
)
rollout zapper "Frank" width:152 height:331
(
pickbutton boltBtn "Lightning Emitter" pos:[15,36] width:113 height:34
pickbutton surfaceBtn "Surface" pos:[15,96] width:113 height:34
label boltLbl "Pick Bolt" pos:[16,13] width:113 height:18 enabled:true
label surfaceLbl "Pick Surface" pos:[15,75] width:113 height:18 enabled:true
button zapBtn "Zap!" pos:[21,274] width:108 height:45
spinner seedSpn "Random Seed " pos:[14,241] width:124 height:16 range:[1,99999,12345] type:#integer
spinner maxJag "Max Jags " pos:[39,179] width:99 height:16 range:[1,100,5] type:#integer
spinner minJag "Min Jags " pos:[39,210] width:99 height:16 range:[1,100,1] type:#integer
spinner boltsSpn "Bolts" pos:[79,148] width:59 height:16 range:[1,100,5] type:#integer
on boltBtn picked obj do
(
boltLbl.text = obj.name
boltEm = obj
)
on surfaceBtn picked obj do
(
surfaceLbl.text = obj.name
boltSurf = obj
)
on zapBtn pressed do
(
if boltEm != undefined and boltSurf != undefined then
(
undo on
(
makeBolts seedSpn.value maxJag.value minJag.value boltsSpn.value
)
)
else
messageBox "Pick an emitter and a surface to continue"
)
)
createDialog zapper
Max 7.5 used
By the way, I’m glad to see people commenting code with headers and such. I usually practice this, but i’m lazy today!
Looks cool Martin. I like the forks. Can’t wait to see it animating.
The animation range is made really huge because of the noise controllers. By default they’re only active for the range of time that is set when they’re added. So this way I make sure they’re not going to just stop if the animation range is made longer after it’s created, like with wire parameters. I wish Autodesk would just get rid of this “feature”, it’s way more annoying than useful.
They should at least allow you to configure it! I always forget to reset my ranges after wiring.
thanks . for all of ur doing will be a good reference for new scripters like me . and i will collected all the challanges. i cant write so fast but i m learning .wish some day i will be a member like u all .