the "walk o matic" script

Hi, I’ve noticed there’s been plenty of threads here asking about the walk o matic script. From 2.32 to 2.42 there’s been at least one thread. However there hasn’t been a 2.43 thread yet so I’m making one :stuck_out_tongue:

Basically it’s the same problem as with every other thread. It gives an error. I’ve downloaded both of the updated files (the 0.4.8 script and the “walking on the ceiling” update.) However it still refuses to work. Here’s the error:


----------------------------------
W A L K - O - M A T I C   V 0.49.7
----------------------------------
Proxy in use:   [Object "Empty.011"] in layer 2
Blender.Scene.getCurrent() is deprecated,
        use Blender.Scene.GetCurrent() instead.
Target scene:   [Scene "1"]
Currently processing: Heel targets
Traceback (most recent call last):
  File "C:\Program Files\Blender Foundation\Blender\.blender\scripts\walkomatic0
.49.7.py", line 286, in ?
    doIt(0, 1, 'Heel targets')
  File "C:\Program Files\Blender Foundation\Blender\.blender\scripts\walkomatic0
.49.7.py", line 218, in doIt
    targetloc = getOffset(proxy, cpf+MT, 1, HS/2, forwardOffset)
  File "C:\Program Files\Blender Foundation\Blender\.blender\scripts\walkomatic0
.49.7.py", line 116, in getOffset
    Blender.Set('curframe',frame)
ValueError: expected an integer

Any idea on what’s wrong/ how to fix it?

Thanks.

Blender.Set(‘curframe’,int(frame)) ?

Ask the author to check it out

I think the author of the script is long gone. (Otherwise i’d think the script would be at v. 1.0 by now?)

Curious, there is a lot of other problems but int(frame) is not needed in blender 2.42

I found the same, however it works with 2.42. As it just creates empties for placing the feet, I have a renamed 2.42. Then append the empties into your 2.43 scene. Doesnt take long.

frames are ints so raising an error is probably a good thing if sombody tries to set it to a float.

i am not feeling any problem. My walk.o.matic is working nicely.

Hi,

Could you publish the version you are using? also are you using Blender 2.43?

I am using Blender 237a, Blender 242a
and version W A L K - O - M A T I C V 0.49.7

Do you have the version updated by someone named jm soler (French person) that works with 2.42a, but not with 2.43 found it here…

http://www.zoo-logique.org/3D.Blender/scripts_python/snippets/walkomatic0.49.8.py

After trying for AGES to get hold of an updated version of this script (and the insect-walk one) both of which seemed to use the old method of frame tracking, I’m also having issues with floats vs. ints:


W A L K - O - M A T I C V 0.49.8

Proxy in use: [Object “Armature”] in layer 8
Blender.Scene.getCurrent() is deprecated,
use Blender.Scene.GetCurrent() instead.
Target scene: [Scene “1”]

Currently processing: Heel targets
Traceback (most recent call last):
File “walk.o.matic.0.49”, line 286, in ?
File “walk.o.matic.0.49”, line 218, in doIt
File “walk.o.matic.0.49”, line 116, in getOffset
ValueError: expected an integer

Anyone cured this yet? My Python programming is useless at best, but I’m pretty sure I can’t see why it thinks that an interger like a frame number has suddenly become a float!

I actually think this script idea is brilliant. A gui for the parameters (and of course a fix for running in 2.43) Would be usefull for a lot of people.

Gotta do this in two posts, as there are too many characters for vBulletin to handle…

 # Jamesk's Walk-o-matic version 0.49.9 (MODIFIED)
# for Blender 2.25 and a fully installed Python 2.0 [required]
# CHANGES FOR BLENDER 2.36 GENERALLY MARKED '#MDR:' ...

# SET/CHECK THE PARAMETERS BELOW BEFORE EXECUTING THE SCRIPT.
# Make sure to select your proxy object, then run the script with ALT+P.
# Please consult the documentation for a full description of the parameters.
# ...Aaaaand check the console window for any messages.

# GENERAL SETTINGS:
FF = FIRST_FRAME = 1        # begin evaluating at this frame
LF = LAST_FRAME = 850       # stop evaluating after this frame

HS = HEEL_SEPARATION = 3.0  # desired distance between heel targets (in Blender Units)
MT = MOVE_TIME = 8.0        # number of frames/cycle a foot is moving
MSD = MOVE_STOP_DELAY = 0   # any value above zero will prolong the time a foot stays in the air.
HEEL_TO_FLAT_DISTANCE = 1   # desired distance between a heel target and its associated foot look-at-target
FLAT_TO_TLAT_DISTANCE = 0.5 # desired distance between a foot look-at-target and its associated toe look-at-target

AL = ALWAYS_LIFT = 0             # set to zero to prevent feet moving up/down when proxy has speed 0
CTD = C_TARG_DISTANCE = 2.0      # how far above proxy to place center target
LA = LIFT_AXIS = 'local'         # lift feet along global Z or local proxy Z?
CTDLA = CTD_LIFT_AXIS = 'global' # raise center target along global Z or local proxy Z?

# NAMES FOR THE EMPTIES:
HEEL_LEFT, HEEL_RIGHT = 'heel.ikt.left', 'heel.ikt.right' 
FLAT_LEFT, FLAT_RIGHT = 'foot.lat.left', 'foot.lat.right' 
TLAT_LEFT, TLAT_RIGHT = 'toe.lat.left', 'toe.lat.right'  
TARGET_CENTRE = 'target.centre'                    

# LIFT ENVELOPE SETTINGS:
LP = LIFT_PEAK = 0.5        # how far to lift above proxy initially 
FLATLP = FLAT_LIFT_PEAK = 0.2 # how far to lift foot look-at-target above proxy initially
TLATLP = TLAT_LIFT_PEAK = 0.2 # how far to lift toe look-at-target above proxy initially
LPT = LIFT_PEAK_TIME = 0.2  # time to reach lift-peak. (relative to movetime)

MP = MID_PEAK = 0.4         # how far from proxy after lift-peak
FLATMP = FLAT_MID_PEAK = 0.4 # how far to lift foot look-at-target
TLATMP = TLAT_MID_PEAK = 0.4 # how far to lift toe look-at-target
MPT = MID_PEAK_TIME = 0.5   # time to reach mid-peak (relative to movetime)

FP = FINAL_PEAK = 0.5       # how far from proxy before setting down again
FLATFP = FLAT_FINAL_PEAK = 0.7 # how far to lift foot look-at-target
TLATFP = TLAT_FINAL_PEAK = 0.9 # how far to lift toe look-at-target
FPT = FINAL_PEAK_TIME = 0.8 # time to reach final_peak (relative to - you guessed it - movetime)


#
# Concept and coding by James Kaufeldt a.k.a. Jamesk 
# Made in Sweden, november 2002
# Contact: [email protected]
#
# Special thanx to
# - [d0pamine] and [theeth] for some hints regarding vector math.
# - Martin [Strubi] Strubel from whom I borrowed the "normalize" function,
#   len3(x), dist3(x,y) and sub3(x,y) funcs found in his "vect.py" utility module.
# - [eeshlo] for pointing out how simple it was to give names to the empties.
#
# ---------------------------------------------------------------------------------------
# EDITABLE SECTION ENDS HERE!
#
# NO USER DEFINABLE VALUES BEYOND THIS POINT!
# ---------------------------------------------------------------------------------------
#
#
#
#

LT = MT
CT = MT + LT  

from Blender import Object, Scene, Window, Ipo
from Blender.Scene import Render
from Blender.Window import Types
import sys, math

proxy = Object.GetSelected()

status = 'UNDEFINED ERROR'
Layer = 0
print
print '----------------------------------'
print 'W A L K - O - M A T I C   V 0.49.9'
print '----------------------------------'
print
# make sure that there's an actual walker proxy to use:
if proxy == []:
    print 'No proxy indicated, terminating...'
    status = 'NO PROXY OBJECT SELECTED'
if proxy != []:
    proxy = proxy[0]
    print 'Proxy in use: 	',proxy
    Layer = proxy.Layer
    print ' in Layer',Layer
    status = 'OK'
sys.stdout.flush()

scene = Scene.GetCurrent()

# make sure there's a scene to use (should always be one, but wth...)
if scene == []:
    print 'No scene available, terminating...'
    status = 'NO CURRENT SCENE AVAILABLE'
if scene != []:
    print 'Target scene: 	',scene
sys.stdout.flush()

# some generally useful functions below:
def normalize(v):
    r = math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
    return (v[0]/r, v[1]/r, v[2]/r)

def len3(x):
    return math.sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2])

def sub3(x, y):
    return ((x[0] - y[0]), (x[1] - y[1]), (x[2] - y[2]))

def dist3(x, y):
    return len3(sub3(x, y))

def moveAlong(origpos, distance, vector):
    newpos = [0,0,0]
    newpos[0] = origpos[0]+distance*vector[0]
    newpos[1] = origpos[1]+distance*vector[1]
    newpos[2] = origpos[2]+distance*vector[2]
    return newpos

def invertVector(v):
    return ((-1*v[0], -1*v[1], -1*v[2]))

#MDR:
def selectFrame(f):
    f = int(f)
    if scene.getRenderingContext().currentFrame() != f:
       scene.getRenderingContext().currentFrame(f)
       Window.Redraw(Window.Types.VIEW3D)

# MDR:
# Conversion routine:  try to get an object, return None if it's not there.
#   Just like Blender used to do.  The easiest way to accomplish this is to
#   allow the exception to occur, and catch it.

def TryGetObject(v):
  try:
    return Object.Get(v)
  except:
    return None


def getOffset(origin, frame, xdir, xdist, forward):
    # origin: the point to offset           frame: framenumber
    # xdir:  1 = positive offset along X, -1 = negative offset
    # xdist: how much to offset
    selectFrame(frame)
    loc = origin.getMatrix()[3]
    loc = moveAlong(loc, forward, normalize(origin.getMatrix()[1]))
    direction = normalize(origin.getMatrix()[0])
    if xdir == -1:
        direction = invertVector(direction)
    return moveAlong(loc, xdist, direction)

def getLiftAxisOffset(origin, frame, liftaxis, liftdist):
    # origin: the point to offset             frame: framenumber
    # liftaxis: 'global' or 'local' lifting   liftdist: the amount of lift    
    selectFrame(frame)
    loc = origin.getMatrix()[3]
    direction = normalize(origin.getMatrix()[2])
    if liftaxis=='global':
        direction = [0,0,1.0]
    return moveAlong(loc, liftdist, direction)

def getElevation(origin, frame, axis, zdist, xdir, xdist, forward):
    # origin: the point to offset     frame: framenumber
    # axis: 'local' or 'global'       zdist: how much to elevate
    # xdir: the X offset              xdist: the distance to offset along X
    loc = getOffset(origin, frame, xdir, xdist, forward)
    if axis=='local':
        direction = normalize(origin.getMatrix()[2])
        return moveAlong(loc, zdist, direction)
    if axis=='global':
        direction = [0, 0, 1.0]
        return moveAlong(loc, zdist, direction)
    
def writeCurvePoint(ipo, frame, point):
    # ipo: the IPOblock to use           frame: at what frame
    # point: the 3D coordinate to write
    xc = ipo.getCurve('LocX')
    yc = ipo.getCurve('LocY')
    zc = ipo.getCurve('LocZ')
    idx = 0
    for c in [xc,yc,zc]:
        c.addBezier((frame, point[idx]))
        idx += 1
        c.update()
     
def makeIPO(name, ipol, expol):
    # name: desired name for this IPOblock    ipol: type of interpolation
    # expol: type of extrapolation
    ipo = Ipo.New('Object', name)
    xc = ipo.addCurve('LocX')
    yc = ipo.addCurve('LocY')
    zc = ipo.addCurve('LocZ')
    for curve in [xc, yc, zc]:
        curve.setInterpolation(ipol)
        curve.setExtrapolation(expol)
    return ipo
def move(ipo, origin, destination, startframe, framespan, proxob, xdir, xdist, forward):
    # ipo - what ipo to write points to                 origin - the location (3Dpoint) to start at
    # destination - the location to end up at           startframe - frame to set the first curvepoint at
    # framespan - total number of frames for the move   proxob - the proxy/reference object
    # xdir - pos or neg offset along proxy X-axis       xdist - how much to offset along proxy X-axis
    writeCurvePoint(ipo, startframe, origin)

    if AL==1 or origin!=destination:
        # Write curvepoints for LiftPeak and LiftPeakTime:
        # Pretty hackish formulae for proxyTime here... But they do work, so wtf...
        lpProxyTime = startframe + (LPT*framespan*2)-framespan*0.25
        lpRealTime = startframe+(framespan+MSD)*LPT
        lpLocation = getElevation(proxob, lpProxyTime, LA, LP, xdir, xdist, forward)
        writeCurvePoint(ipo, lpRealTime, lpLocation)
        # Write curvepoints for MidPeak and MidPeakTime:
        mpProxyTime = startframe + (MPT*framespan*2)-framespan*0.25
        mpRealTime = startframe+(framespan+MSD)*MPT
        mpLocation = getElevation(proxob, mpProxyTime, LA, MP, xdir, xdist, forward)
        writeCurvePoint(ipo, mpRealTime, mpLocation)
        # Write curvepoints for FinalPeak and FinalPeakTime:
        fpProxyTime = startframe + (FPT*framespan*2)-framespan*0.25
        fpRealTime = startframe+(framespan+MSD)*FPT
        fpLocation = getElevation(proxob, fpProxyTime, LA, FP, xdir, xdist, forward)
        writeCurvePoint(ipo, fpRealTime, fpLocation)
    
    writeCurvePoint(ipo, startframe+framespan+MSD, destination)
    return (startframe+framespan, destination)

def hold(ipo, location, startframe, framespan):
    # ipo - what ipo to write points to                 # location - the position (3Dpoint) to hold at
    # startframe - the first frame in the hold sequence # framespan - total number of frames to hold
    writeCurvePoint(ipo, startframe+MSD, location)
    writeCurvePoint(ipo, startframe+framespan, location)
    return (startframe+framespan, location)

def recalculator(assignedTargets, targ1, targ2, basetarg):
    # rewrites some globals based on the current arrangement of the empties:
    loc1 = targ1.getLocation()
    loc2 = targ2.getLocation()
    loc3 = basetarg.getLocation()
    # HEEL_SEPARATION:
    if assignedTargets=='heels':
        print 'Default heel empties found. Recalculating:'
        global HS
        HS = dist3(loc1, loc2)
        print 'HEEL_SEPARATION set to',HS
    if assignedTargets=='flats':
        print 'Default foot look-at targets found. Reusing.'
        global HEEL_TO_FLAT_DISTANCE
        HEEL_TO_FLAT_DISTANCE = dist3(loc2, loc3)
        print 'HEEL_TO_FLAT_DISTANCE set to', HEEL_TO_FLAT_DISTANCE
    if assignedTargets=='tlats':
        print 'Default toe look-at targets found. Reusing.'
        global FLAT_TO_TLAT_DISTANCE
        FLAT_TO_TLAT_DISTANCE = dist3(loc2, loc3)
        print 'FLAT_TO_TLAT_DISTANCE set to',FLAT_TO_TLAT_DISTANCE
    

def doIt(forwardOffset, addCenter, whatsUp, firstName, secondName):
    print
    print 'Currently processing:',whatsUp
    # Start building the IPO for the right foot:
    ffootipo = makeIPO('rfoot', 'Linear', 'Constant')
    cpf = currentProxyFrame = FF

    # make first step (only half as far as the others):
    ffootloc = getOffset(proxy, cpf, 1, HS/2, forwardOffset)
    ffootframe = cpf
    targetloc = getOffset(proxy, cpf+MT, 1, HS/2, forwardOffset)
    ffootframe, ffootloc = move(ffootipo, ffootloc, targetloc, ffootframe, MT/2,proxy, 1, HS/2, forwardOffset)
    ffootframe, ffootloc = hold(ffootipo, ffootloc, ffootframe, LT)

    # now make the rest of the steps (full length):
    done = 0
    while not done:
        cpf += CT
        targetloc = getOffset(proxy, cpf+MT, 1, HS/2, forwardOffset)
        ffootframe, ffootloc = move(ffootipo, ffootloc, targetloc, ffootframe, MT,proxy, 1, HS/2, forwardOffset)
        ffootframe, ffootloc = hold(ffootipo, ffootloc, ffootframe, LT)
        if cpf>LF:
            done=1
   
    # Then we'll build the IPO for the left foot:
    sfootipo = makeIPO('lfoot', 'Linear', 'Constant')
    cpf = currentProxyFrame = FF

    # this one starts in hold-mode (waits for right foot to finish)
    sfootloc = getOffset(proxy, cpf, -1, HS/2, forwardOffset)
    sfootframe = cpf
    sfootframe, sfootloc = hold(sfootipo, sfootloc, cpf, MT/2)

    done = 0
    while not done:
        cpf += CT
        targetloc = getOffset(proxy, cpf, -1, HS/2, forwardOffset)
        sfootframe, sfootloc = move(sfootipo, sfootloc, targetloc, sfootframe, MT,proxy, -1, HS/2, forwardOffset)
        sfootframe, sfootloc = hold(sfootipo, sfootloc, sfootframe, LT)
        if cpf>LF:
            done=1

    if addCenter:
        # And to finish it off, let's put something in the middle of this:
        # This will simply add a third target floating above the proxy.
        # It will respect the specified lift axis, hence useful as parent for an armature
        ctargetipo = makeIPO('center', 'Linear', 'Constant')
        for cframe in range(FF, LF):
            targetloc = getLiftAxisOffset(proxy, cframe, CTDLA, CTD)
            writeCurvePoint(ctargetipo, cframe, targetloc)

    # Finished. Add or reuse empties and link them to their respective IPOblocks.
    leftikt = TryGetObject(firstName)
    leftnew = 0
    if leftikt==None:
        leftikt = Object.New('Empty')
        leftnew = 1
        
    rightikt = TryGetObject(secondName)
    rightnew = 0
    if rightikt==None:
        rightikt = Object.New('Empty')
        rightnew = 1
    leftikt.name = firstName
    rightikt.name = secondName
    print 'Targets',leftikt,rightikt
    if addCenter:
        centertarget = TryGetObject(TARGET_CENTRE)
        centernew = 0
        if centertarget==None:
            centertarget = Object.New('Empty')
            centernew = 1
        centertarget.name = TARGET_CENTRE
        print 'Centertarget',centertarget
        centertarget.Layer = Layer
        if centernew: 
            scene.link(centertarget)
        
        #MDR: 'SetIPO' was 'link'...
        centertarget.setIpo(ctargetipo)
    leftikt.Layer = Layer
    rightikt.Layer = Layer
    if leftnew: 
        scene.link(leftikt)
    if rightnew: 
        scene.link(rightikt)
        
    #MDR: Ditto... 'setIpo' was 'link'...
    leftikt.setIpo(sfootipo)
    rightikt.setIpo(ffootipo)
    print whatsUp,'IPO:s',sfootipo,ffootipo
    print '---------------------------------------------------------'
    sys.stdout.flush()
    


#########################################
# if everything's OK, let's get to work #
#########################################
if status=='OK':
    currentUserFrame = scene.getRenderingContext().currentFrame()

    # grab any walkomat empties left in the scene:
    oldleftheel =TryGetObject(HEEL_LEFT)
    oldrightheel =TryGetObject(HEEL_RIGHT)

    oldleftflat =TryGetObject(FLAT_LEFT)
    oldrightflat =TryGetObject(FLAT_RIGHT)

    oldlefttlat =TryGetObject(TLAT_LEFT)
    oldrighttlat=TryGetObject(TLAT_RIGHT)

    emptyipo = makeIPO('emptydummy', 'Linear', 'Constant')

    # recalculate if there were any such empties:
    if oldleftheel!=None and oldrightheel!=None:
        # assign an empty IPO first to clear any anim:
        # why isn't there some 'unlink' function somewhere???
        #
        # MDR: These 'setIpo' calls were 'link' ....
        #
        oldleftheel.setIpo(emptyipo)
        oldrightheel.setIpo(emptyipo)
        recalculator('heels', oldleftheel, oldrightheel, oldrightheel)

    if oldleftflat!=None and oldrightflat!=None:
        oldleftflat.setIpo(emptyipo)
        oldrightflat.setIpo(emptyipo)
        recalculator('flats', oldleftflat, oldrightflat, oldrightheel)

    if oldlefttlat!=None and oldrighttlat!=None:
        oldlefttlat.setIpo(emptyipo)
        oldrighttlat.setIpo(emptyipo)
        recalculator('tlats', oldlefttlat, oldrighttlat, oldrightflat)

    # first pass, heel targets:
    doIt(0, 1, 'Heel targets', HEEL_LEFT, HEEL_RIGHT)

    #second pass, foot look-at targets:
    LP = FLATLP
    MP = FLATMP
    FP = FLATFP
    doIt(HEEL_TO_FLAT_DISTANCE, 0, 'Foot look-at targets', FLAT_LEFT, FLAT_RIGHT)

    #third pass, toe look-at targets:
    LP = TLATLP
    MP = TLATMP
    FP = TLATFP
    doIt(HEEL_TO_FLAT_DISTANCE+FLAT_TO_TLAT_DISTANCE, 0, 'Toe look-at targets', TLAT_LEFT, TLAT_RIGHT)

    # At last, as a friendly gesture, restore the frame to whatever the user
    # was looking at before running the script, and refresh the screens:  
    scene.getRenderingContext().currentFrame(currentUserFrame)
    Window.RedrawAll()
    print 'Processing completed.'
    print 'Thank you for using Walk-O-Matic :D'
    sys.stdout.flush()

    
###################################################
# if things are not right, print some dying words:#
###################################################
if status!='OK':
    print ''
    print 'Walk-o-matic is sadly forced to report that'
    print 'it could not go to work properly.'
    print 'Cause of termination: ',status
    print 'Please consult the documentation regarding proper use.'
    sys.stdout.flush()

Now I’ve just got to try and find a working ‘insect-walk’ script that doesn’t give me this error:

Traceback (most recent call last):
File “D:\Program Files\Blender Foundation\Blender.blender\scripts\insect-walk-0.4.1.py”, line 540, in bevent
elif (evt== 12): walkInsect()
File “D:\Program Files\Blender Foundation\Blender.blender\scripts\insect-walk-0.4.1.py”, line 356, in walkInsect
if iCenter != None: iCenter.link(voidIpo[0])
AttributeError: link argument type is not supported

That version does not work…

Sorry Roy, I’m not sure whether you mean the ‘walk-o-matic’ or ‘insect-walk’ scripts - which doesn’t work for you?

I’ve tested the ‘walk-o-matic’ on my machine and it seems to work fine, but I’m still having trouble with the ‘insect-walk’, which I’ve managed to get running, but which inverts the leg positions on the left hand side of the model - once I’ve had more progress with that one I’ll open another thread for them both.

Sorry, I thought the script in 2 posts was the walk-0 matic, Pls ignore me! and I hope you manage to make progress. Unfortunately I know nothing about Python!
Any chance of a Gui for walk-o-matic? :slight_smile:

The script in two posts IS walk-o-matic - with a couple of tweaks. Cut and paste both posts into a single .py file and it should work (sorry for not just linking to the file, but I’ve got nowhere to upload it to). It seems to work fine on my machine (with Blender 2.43 and Python 2.4.4) , but if you’re getting any errors with it, post back with the errors along with your Blender, Python and OS versions and we’ll try and get it running for you. Once there’s a version that seems to be error free, I’ll give a GUI a try.

why didn’t you post as code? indentation is all screwed up.