Chapter 2 · Examples

2.7Storm Stage

This example builds a whole animated shot, TenPix and native 3ds Max together: a ground plane, an animated pole, a flag whose edge is painted and pinned to the pole entirely from script, a Wind whose strength is keyed calm, storm, calm, a Vortex waiting muted in the list, and TurboSmooth on top of the simulation.

(
    animationRange = interval 0 120
    local ground = Plane length:600 width:600 pos:[0,0,0] wirecolor:gray
    local pole = Cylinder radius:2 height:150 pos:[-60,0,0] wirecolor:orange
    animate on (
        at time 0   pole.pos = [-60,0,0]
        at time 60  pole.pos = [-60,25,0]
        at time 120 pole.pos = [-60,0,0]
    )
    -- the flag is built flat at the origin so it can be painted in easy coordinates,
    -- then stood up and moved onto the pole at the end
    local flag = Plane length:60 width:110 lengthsegs:1 widthsegs:1 wirecolor:red
    addModifier flag (Tnpix_Garment())
    flag.modifiers[#Tnpix_Garment].edgeLength = 2.2
    -- the held edge: a channel painted along the flag's left edge (x = -55 in its own space)
    addModifier flag (Tnpix_Channel())
    select flag
    max modify mode
    modPanel.setCurrentObject flag.modifiers[#Tnpix_Channel]   -- painting needs the Channel panel open
    completeRedraw()
    TnpixTool.chanAdd flag "pole_edge" 0.0
    for y = -30.0 to 30.0 by 3.0 do TnpixTool.chanPaint flag [-55, y, 0] 3.0 0 1.0
    format "%\n" (TnpixTool.chans flag)
    addModifier flag (Tnpix_Pin())
    TnpixTool.pinSet flag "pole_edge" 1.0 pole       -- weight 1.0 = follows the pole completely
    addModifier flag (Tnpix_Self_Collision())
    flag.modifiers[#Tnpix_Self_Collision].tnEnabled = true
    addModifier flag (Tnpix_Gravity())
    local w = Wind pos:[-250,-250,100] strength:0.2 decay:0.0 turbulence:0.3 frequency:2.0
    w.rotation = eulerAngles 90 0 45
    animate on (
        at time 0   w.strength = 0.2
        at time 45  w.strength = 3.0
        at time 80  w.strength = 3.0
        at time 120 w.strength = 0.3
    )
    local v = Vortex pos:[80,80,0]
    addModifier flag (Tnpix_Forces())
    append flag.modifiers[#Tnpix_Forces].forceNodes w;  append flag.modifiers[#Tnpix_Forces].forceMuted 0
    append flag.modifiers[#Tnpix_Forces].forceNodes v;  append flag.modifiers[#Tnpix_Forces].forceMuted 1
    local s = Tnpix_Solver()
    s.substeps   = 4
    s.iterations = 3
    addModifier flag s
    addModifier flag (TurboSmooth iterations:1)
    -- into place: standing up, its left edge on the top of the pole
    flag.rotation = eulerAngles 90 0 0
    flag.pos = [-2, 0, 115]
    format "STORM STAGE READY - press Play.\n"
)

What you should see: a small stage appears, the script prints the channel table with pole_edge in it, and the Pin panel shows the channel as bound. On Play the flag hangs calm from the pole, whips hard as the keyed storm rises, then settles as the wind dies, while the pole sways and the flag's edge follows it. The Vortex waits muted: flag.modifiers[#Tnpix_Forces].forceMuted[2] = 0 adds swirl without touching the scene. TurboSmooth makes the rendered flag smoother than the simulated one: native modifiers above the cloth stack.