Help getting the old "Insect Procedural Walk" script working!

Hi!

I’ve been trying to get the insect walking script working. The web page is dead but is alive in the archives here .

I’ve tried using a whole bunch of different versions of Blender in virtualised Windows XP under Linux (as I had trouble getting old versions running under linux) with no luck.

Every time I click, run errors pop up about undefined methods in bevent. A typical line that generates such an error looks something like this:

layer = proxy.layer

Somehow, I’m pretty sure this is a Blender problem and not to do with the install Python version.

If anyone knows of an updated version of the script that would be terrific but if not, all help would be greatly appreciated anyways!

Thanks,

Koba

http://www.zoo-logique.org/3D.Blender/scripts_python/API/Object.Object-class.html#layers

Hi,

I’ve taken time to fix the script. The script is under the Blender Artistic License so I’m not sure if I’m allowed to redistribute it without the authors permission (though I guess it would be ok!)

If anyone wants the new working script, just ask!

Koba

BAL is good for redistribute, attribution style.
post the fixed script.
always attribute the original author properly then there is no problem.
if you like, contact me & i will upload the new script to the BlenderWiki servers & it could be hosted there.
which i would like to do!
Brendon.

Hi!

Ok then, the original lines are still commented out but here it is! (across 3 posts, sorry!). Not saying I know what I’m doing but it works! I’m not going to credit myself with something this simple.


# --------------------------------------------------------------------------------------- #
#   Procedural Insect Walk
#
#   By Laurent Wibaux <wibauxl>, parts by <theeth>
#   Released under the Blender Artistic Licence (BAL)
#   See www.blender.org
# --------------------------------------------------------------------------------------- #

# ---- Special thanks to <theeth> for the following procedures ---------------------------#
#   From vecf.py:
#       vecDot, vecNorm, vecSub, vecCross, vecProj
#       matrixToEulerRot
#   From Track_Axis.py:
#       getTrackingRotationMatrix
# --------------------------------------------------------------------------------------- #

# ---- History -------------------------------------------------------------------------- #
#   0.4   2003-09-01  First public release
# --------------------------------------------------------------------------------------- #


# ---- Constants ------------------------------------------------------------------------ #

VERSION = 0.4

# Naming of the objects to create
LENP = LEG_END_NAME_PREFIX = 'L'                # Construction is Proxy_Name.[LENP]LegNum[LENS].Side
LENS = LEG_END_NAME_SUFFIX = 'E'                # i.e.: Proxy_Name.L1E.R, Proxy_Name.L3E.L
CENTER = 'C'                                    # the center object: Proxy_Name.C

# End of user defined variables

# Constants
RP = RIGHT_PAIR = 0
LP = LEFT_PAIR = 1

# General settings
FF = FIRST_FRAME = 1                            # begin evaluating at this frame
LF = LAST_FRAME = 100                           # stop evaluating after this frame

# Dynamics of the movement
MT = MOVE_TIME = 6                              # number of frames/cycle a leg is moving 
                                                # an even number greater than 0
                                                                                            
# Description of the body of the insect
LAX = LEG_ATTACHMENT_X = [0.3, 0.45, 0.4, 0.35] # position of each leg of a pair from the proxy center
LAY = LEG_ATTACHMENT_Y = [0.6, 0.0, -0.6, -1.2] # position of each pair of leg from the proxy center 
LAZ = LEG_ATTACHMENT_Z = [1.5, 1.5, 1.5, 1.5]   # height of the leg attachment from the proxy
LSL = LEG_SHADOW_LENGTHS = [[3.0, 3.5, 3.0, 3.0],   # total length of the cord of the right legs
                            [3.0, 3.5, 3.0, 3.0]]   # total length of the cord of the left legs
LSE = LEG_STEP_ELEVATION = [0.5, 0.5, 0.5, 0.5]     # elevation of the legs during a step
LRR = LEG_REST_ROTATIONS = [[30.0, 0.0, -30.0, -50.0],     # max rotation of the right legs (in degrees)
                            [150.0, 180.0, -150.0, -130.0]] # max rotation of the left legs (in degrees)
SIZING_RATIO = 1.0                              # ratio to apply to the 
NPL = NUMBER_OF_PAIR_OF_LEGS = 4                # number of pair of legs

# --------------------------------------------------------------------------------------- #
#   Data initialization
# --------------------------------------------------------------------------------------- #

from Blender import Object, Scene, Window, Ipo, NMesh, Draw, BGL
import math

#proxy = Object.Get("Ant")
proxy = Object.GetSelected()
#print proxy
scene = Scene.getCurrent()
lastLegP =[list(), list()]
legRestRP =[list(), list()]
lastLegRot =[list(), list()]
legAtt = list()
legElev = list()
legShadows =[list(), list()]
legRestRot =[list(), list()]
for legNum in range(NPL):
    legAtt.append([Draw.Create(LAX[legNum]), Draw.Create(LAY[legNum]), Draw.Create(LAZ[legNum])])
    legElev.append(Draw.Create(LSE[legNum]))
    for side in range(2):
        lastLegP[side].append([0.0, 0.0, 0.0])
        legRestRP[side].append([0.0, 0.0, 0.0])
        lastLegRot[side].append([0.0, 0.0, 0.0])
        legShadows[side].append(Draw.Create(LSL[side][legNum]))
        legRestRot[side].append(Draw.Create(LRR[side][legNum]))
startFrame = Draw.Create(FF)
endFrame = Draw.Create(LF)
stepLength = Draw.Create(MT)
sizingRatio = Draw.Create(SIZING_RATIO)
NPL = 3
nbLegs = Draw.Create(NPL)
msgString = "Ready"
if proxy != []: proxyName = Draw.Create(proxy[0].name)
else: proxyName = Draw.Create("")


# --------------------------------------------------------------------------------------- #
#   Vector utils
# --------------------------------------------------------------------------------------- #

def vecDot(v1, v2):
    return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]

def vecNorm(v):
    det = vecDot(v, v)
    if det>0.0: 
        det = 1.0/math.sqrt(det)
        v[0] *= det
        v[1] *= det
        v[2] *= det
    return v

def vecSub(a, b):
    return [a[0]-b[0], a[1]-b[1], a[2]-b[2]]    

def vecCross(v1, v2):
    r = [0.0, 0.0, 0.0]
    r[0] = v1[1]*v2[2] - v1[2]*v2[1]
    r[1] = v1[2]*v2[0] - v1[0]*v2[2]
    r[2] = v1[0]*v2[1] - v1[1]*v2[0]
    return r

def vecProj(v2, v1):
    factor = vecDot(v1, v2)/vecDot(v1, v1)
    return [factor*v1[0], factor*v1[1], factor*v1[2]]
    
# --------------------------------------------------------------------------------------- #
#   Matrix utils
# --------------------------------------------------------------------------------------- #
    
def relToAbs3(referenceO, relativeP):    
    # params:   referenceO: the object to relate to
    #           relativeP:  the position relative to the reference object
    # returns:  the absolute position of relativeP 
    absP = [0, 0, 0]
    oMat = referenceO.getMatrix()
    absP[0] = oMat[0][0]*relativeP[0] + oMat[1][0]*relativeP[1] + oMat[2][0]*relativeP[2] + oMat[3][0]
    absP[1] = oMat[0][1]*relativeP[0] + oMat[1][1]*relativeP[1] + oMat[2][1]*relativeP[2] + oMat[3][1]
    absP[2] = oMat[0][2]*relativeP[0] + oMat[1][2]*relativeP[1] + oMat[2][2]*relativeP[2] + oMat[3][2]
    return absP    

def rotateMatrix90Degree(mat):
    # params:   mat: the 3x3 matrix to rotate
    # returns:  a rotated matrix by 90° around Z 
    return [[-mat[1][0], -mat[1][1], -mat[1][2]], 
            [mat[0][0], mat[0][1], mat[0][2]], 
            [mat[2][0], mat[2][1], mat[2][2]]]
    
def matrixToEulerRot(mat): 
    # params:   mat: the 3x3 from which to exctract the Euler angles
    # returns:  the Euler rotation angles
    mtx =[list(mat[0][:3]), list(mat[1][:3]), list(mat[2][:3])] 
    angle_y = -math.asin(max(min(mtx[0][2], 1.0), -1.0)) 
    C = math.cos(angle_y) 
    if C != 0.0: C = 1.0/C 
    angle_x = math.atan2(mtx[1][2] * C, mtx[2][2] * C) 
    angle_z = math.atan2(mtx[0][1] * C, mtx[0][0] * C)
    return [angle_x, angle_y, angle_z]
    
def getTrackingRotationMatrix(targetP, trackingP, rotationPlanNormalV):
    # params:   targetP:    the point to look at
    #           trackingP:  the point to look from
    #           rotationPlanNormalV:  the normal of the plan on which the tracking rotation occurs
    # returns:  the rotation matrix to apply so that the object at trackingP point to targetP
    AB = vecSub(targetP, trackingP)
    T1 = vecNorm(vecSub(AB, vecProj(AB, rotationPlanNormalV)))
    T2 = vecNorm(vecCross(T1, rotationPlanNormalV))
    return [T2, T1, rotationPlanNormalV]
     


# --------------------------------------------------------------------------------------- #
#   IPO utils
# --------------------------------------------------------------------------------------- #
    
def writeLocIPOCurvePoint(ipo, frame, point):
    # inputs:   ipo: the IPOblock to use    
    #           frame: at what frame 
    #           point: the 3D coordinate to write 
    idx = 0
    for c in [ipo[1], ipo[2], ipo[3]]:
        c.addBezier((frame, point[idx]))
        c.update()
        idx += 1

def writeRotIPOCurvePoint(ipo, frame, point):
    # inputs:   ipo: the IPOblock to use    
    #           frame: at what frame 
    #           point: the 3D coordinate to write 
    idx = 0
    for c in [ipo[4], ipo[5], ipo[6]]:
        c.addBezier((frame, point[idx]))
        c.update()
        idx += 1
        
def makeRotLocIPO(name, ipol, expol):
    # inputs:   name: desired name for this IPOblock    
    #           ipol: type of interpolation 
    #           expol: type of extrapolation 
    # outputs:  list of [ipo, newcurves] 
    ipo = Ipo.New('Object', name)
    lxc = ipo.addCurve('LocX')
    lyc = ipo.addCurve('LocY')
    lzc = ipo.addCurve('LocZ')
    rxc = ipo.addCurve('RotX')
    ryc = ipo.addCurve('RotY')
    rzc = ipo.addCurve('RotZ')
    for curve in [lxc, lyc, lzc, rxc, ryc, rzc]:
        curve.setInterpolation(ipol)
        curve.setExtrapolation(expol)
    return [ipo, lxc, lyc, lzc, rxc, ryc, rzc]


  


# --------------------------------------------------------------------------------------- #
#   Main functions
# --------------------------------------------------------------------------------------- #
    
def getLegName(legNum, side):
    return proxy.name + "." + LENP + str(legNum) + LENS + "." + side
    
def createLegEnd(legName):
    legEnd = Object.Get(legName)
    if legEnd == None:
        legEnd = Object.New('Empty')
        legEnd.name = legName
        scene.link(legEnd)

def calculateLegUpP(side, legNum):
    global lastLegP
    legEndP = [legRestRP[side][legNum][0], legRestRP[side][legNum][1], 0.0]
    legEndAbsP = relToAbs3(proxy, legEndP)
    hasMoved = 0
    for i in range(3): 
        if abs(legEndAbsP[i]-lastLegP[side][legNum][i]) > 0.02: hasMoved = 1
    if hasMoved == 1:
        pMat = proxy.getMatrix()
        legEndP[i] = legEndP[i] + pMat[2][i]*LSE[legNum]
        return relToAbs3(proxy, legEndP)
    else:
        return lastLegP[side][legNum]

def calculateLegDownP(side, legNum):
    global lastLegP
    legEndP = [legRestRP[side][legNum][0], legRestRP[side][legNum][1], 0.0]
    legEndAbsP = relToAbs3(proxy, legEndP)
    hasMoved = 0
    for i in range(3): 
        if abs(legEndAbsP[i]-lastLegP[side][legNum][i]) > 0.02: hasMoved = 1
    if hasMoved == 1:
         for i in range(3): lastLegP[side][legNum][i] = legEndAbsP[i]
    return lastLegP[side][legNum]

    
def calculateLegRot(side, legNum, proxyNormV, checkOverflow):
    global lastLegRot, lastLegP, LAX, LAY
    legA = [LAX[legNum], LAY[legNum], 0.0]
    if side == LP: legA[0] = -LAX[legNum]
    rotMat = getTrackingRotationMatrix(relToAbs3(proxy, legA), lastLegP[side][legNum], proxyNormV)
    eulerRot = matrixToEulerRot(rotateMatrix90Degree(rotMat))
    # check that we don't overflow the angles
    if checkOverflow != 0:
        for i in range(3):
            if abs(eulerRot[i] - lastLegRot[side][legNum][i]) > math.pi:
                if lastLegRot[side][legNum][i] < 0: eulerRot[i] = -2*math.pi + eulerRot[i] 
                if lastLegRot[side][legNum][i] > 0: eulerRot[i] = 2*math.pi + eulerRot[i] 
    for i in range(3): lastLegRot[side][legNum][i] = eulerRot[i]
    return eulerRot
           
def writeLegIpos(frame, legIpos, isL1RMoving, isLegUp):
    global lastLegP
    if isL1RMoving == 1:
        # move L1R, L2L, L3R, L4L
        for legNum in range(NPL):
            if legNum == 0 or legNum == 2: 
                if isLegUp == 0:
                    writeLocIPOCurvePoint(legIpos[RP][legNum], frame, lastLegP[RP][legNum])
                    writeLocIPOCurvePoint(legIpos[LP][legNum], frame, calculateLegDownP(LP, legNum))
                else:
                    writeLocIPOCurvePoint(legIpos[RP][legNum], frame, calculateLegUpP(RP, legNum))
            if legNum == 1 or legNum == 3: 
                if isLegUp ==0:
                    writeLocIPOCurvePoint(legIpos[LP][legNum], frame, lastLegP[LP][legNum])
                    writeLocIPOCurvePoint(legIpos[RP][legNum], frame, calculateLegDownP(RP, legNum))
                else:
                    writeLocIPOCurvePoint(legIpos[LP][legNum], frame, calculateLegUpP(LP, legNum))
    else:
        # move L1L, L2R, L3L, L4R
        for legNum in range(NPL):
            if legNum == 0 or legNum == 2: 
                if isLegUp == 0:
                    writeLocIPOCurvePoint(legIpos[RP][legNum], frame, calculateLegDownP(RP, legNum))
                    writeLocIPOCurvePoint(legIpos[LP][legNum], frame, lastLegP[LP][legNum])
                else:
                    writeLocIPOCurvePoint(legIpos[LP][legNum], frame, calculateLegUpP(LP, legNum))
            if legNum == 1 or legNum == 3: 
                if isLegUp ==0:
                    writeLocIPOCurvePoint(legIpos[LP][legNum], frame, calculateLegDownP(LP, legNum))
                    writeLocIPOCurvePoint(legIpos[RP][legNum], frame, lastLegP[RP][legNum])
                else:
                    writeLocIPOCurvePoint(legIpos[RP][legNum], frame, calculateLegUpP(RP, legNum))
    if isLegUp == 0:
        proxyNormV = vecNorm(proxy.getMatrix()[2])
        for legNum in range(NPL):
            writeRotIPOCurvePoint(legIpos[RP][legNum], frame, calculateLegRot(RP, legNum, proxyNormV, 1))
            writeRotIPOCurvePoint(legIpos[LP][legNum], frame, calculateLegRot(LP, legNum, proxyNormV, 1))

def walkInsect():
    global LRR, LAX, LAY, LSL, LSE, NPL
    global legRestRP, lastLegP
    global scene, proxy, proxyName, msgString
    
    proxy = None
    layer = 0
    status = 'UNDEFINED ERROR'
    lastBodyRot = [0.0, 0.0, 0.0]
    NPL = nbLegs.val
    for legNum in range(NPL):
        LAX[legNum] = sizingRatio.val*legAtt[legNum][0].val
        LAY[legNum] = sizingRatio.val*legAtt[legNum][1].val
        LAZ[legNum] = sizingRatio.val*legAtt[legNum][2].val
        LSE[legNum] = sizingRatio.val*legElev[legNum].val
        for side in range(2):
            LRR[side][legNum] = legRestRot[side][legNum].val*math.pi/180
            LSL[side][legNum] = sizingRatio.val*legShadows[side][legNum].val
            legRestRP[side][legNum][0] = math.cos(LRR[side][legNum])*LSL[side][legNum] + LAX[legNum]
            if side == LP: legRestRP[side][legNum][0] -= 2*LAX[legNum]
            legRestRP[side][legNum][1] = math.sin(LRR[side][legNum])*LSL[side][legNum] + LAY[legNum]

    # make sure that there's an actual walker proxy to use:
    if len(proxyName.val) >= 1: proxy = Object.Get(proxyName.val)
    if proxy == None:
        status = 'Proxy object does not exist'
    else:
        layer = proxy.layers # ADDED s!
        status = 'OK'
    
    scene = Scene.getCurrent()
    if scene == []:
        status = 'No scene selected'
    
    if status=='OK':
        print dir(scene)
        context = scene.getRenderingContext()
        currentUserFrame = context.currentFrame() # WAS scene.currentFrame()
        if context.currentFrame() != startFrame.val:
            context.currentFrame(startFrame.val)
            Window.Redraw() # Was 'View'
        
        # initialize the positions of the empties
        lastBodyRot = matrixToEulerRot(proxy.getMatrix())
        proxyNormV = vecNorm(proxy.getMatrix()[2])
        for n in range(NPL):
            calculateLegDownP(RP, n)
            calculateLegDownP(LP, n)
            calculateLegRot(RP, legNum, proxyNormV, 0)
            calculateLegRot(RP, legNum, proxyNormV, 0)
        
        voidIpo = makeRotLocIPO('void', 'Linear', 'Constant')
        print dir(voidIpo[0])
        # clear any ipo left
        iCenter = Object.Get(proxy.name + "." + CENTER)
        if iCenter != None: iCenter.ipo = None
        for legNum in range(NPL):
            legEnd = Object.Get(getLegName(legNum+1, "R"))
            if legEnd != None: legEnd.ipo = None
            legEnd = Object.Get(getLegName(legNum+1, "L"))
            if legEnd != None: legEnd.ipo = None


## USED TO BE!

#        if iCenter != None: iCenter.link(voidIpo[0])
#        for legNum in range(NPL):
#            legEnd = Object.Get(getLegName(legNum+1, "R"))
#            if legEnd != None: legEnd.link(voidIpo)
#            legEnd = Object.Get(getLegName(legNum+1, "L"))
#            if legEnd != None: legEnd.link(voidIpo)
    

  
 



        # define the body centre
        if iCenter == None: 
            iCenter = Object.New('Empty')
            iCenter.name = proxy.name + "." + CENTER
            scene.link(iCenter)
    
        # define the leg end
        for legNum in range(NPL):
            legEnd = Object.Get(getLegName(legNum+1, "R"))
            if legEnd == None: createLegEnd(getLegName(legNum+1, "R"))
            legEnd = Object.Get(getLegName(legNum+1, "L"))
            if legEnd == None: createLegEnd(getLegName(legNum+1, "L"))
    
        # define the ipos
        iCenterIpo = makeRotLocIPO("ipo." + proxy.name + "." + CENTER, 'Linear', 'Constant')
        legIpos = [list(), list()]     
        for legNum in range(NPL):
            legIpos[RP].append(makeRotLocIPO("ipo." + getLegName(legNum+1, "R"), 'Linear', 'Constant'))
            legIpos[LP].append(makeRotLocIPO("ipo." + getLegName(legNum+1, "L"), 'Linear', 'Constant'))
            
        isL1RMoving = 0
        cpf = startFrame.val
        while cpf <= endFrame.val:
       
            if scene.getRenderingContext().currentFrame() != cpf:
                scene.getRenderingContext().currentFrame(cpf)
                Window.Redraw()
            msgString = "Processing frame " + str(cpf) + "/" + str(endFrame.val); Draw.Draw()
            # Move the center
            writeLocIPOCurvePoint(iCenterIpo, cpf, relToAbs3(proxy, [0, 0, LAZ[1]]))
            eulerRot = matrixToEulerRot(proxy.getMatrix())
            for i in range(3):
                if abs(eulerRot[i] - lastBodyRot[i]) > math.pi:
                    if lastBodyRot[i] < 0: eulerRot[i] = -2*math.pi + eulerRot[i] 
                    if lastBodyRot[i] > 0: eulerRot[i] = 2*math.pi + eulerRot[i] 
            for i in range(3): lastBodyRot[i] = eulerRot[i]
            writeRotIPOCurvePoint(iCenterIpo, cpf, eulerRot)
            # Move legs, alternate left and right pair
            isL1RMoving += 1
            if isL1RMoving == 2: isL1RMoving = 0
            writeLegIpos(cpf, legIpos, isL1RMoving, 0)
            cpf = cpf + stepLength.val/2
            # move the leg up, making sure we don't end up with a leg up
            if cpf + stepLength.val/2 < endFrame.val:
                writeLegIpos(cpf, legIpos, isL1RMoving, 1)
            cpf = cpf + stepLength.val/2
            
        # link the ipos
        iCenter.ipo = iCenterIpo[0] # was link(iCenterIpo[0])
        iCenter.layers = layer #Added s!
        for legNum in range(NPL):
            legEnd = Object.Get(getLegName(legNum+1, "R"))
            legEnd.ipo = legIpos[0][legNum][0]   # was link(legIpos[0][legNum][0])
            legEnd.layers = layer
            legEnd = Object.Get(getLegName(legNum+1, "L"))
            legEnd.ipo = legIpos[1][legNum][0] # WAS link(legIpos[1][legNum][0])
            legEnd.layers = layer
        
        # 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()
        msgString = "Ready"; Draw.Draw()
    else:
        msgString = status; Draw.Draw()

# --------------------------------------------------------------------------------------- #
#   GUI definition
# --------------------------------------------------------------------------------------- #
              
def makeInsectSymetrical():
    global legShadows, legRestRot
    for n in range(3):
        if legRestRot[RP][n].val >= 0: legRestRot[LP][n].val = 180-legRestRot[RP][n].val
        else: legRestRot[LP][n].val = -180-legRestRot[RP][n].val
        legShadows[LP][n].val = legShadows[RP][n].val
    Draw.Redraw()
    
def paintSectionTitle(text, x, y, w):
    BGL.glColor3f(0.8, 0.8, 0.8)
    BGL.glRectf(x-5, y-7, x+w+4, y+14)
    BGL.glColor3f(0.65, 0.65, 0.65)
    BGL.glRectf(x-3, y-5, x+w+2, y+12)
    BGL.glColor3f(0.0, 0.0, 0.0)
    BGL.glRasterPos2i(x+2, y)
    Draw.Text(text)
    
def draw():
    X, Y, W = 16, 116, 316
    
    global proxyName, startFrame, endFrame, stepLength, msgString
    global legAtt, legShadows, legElev, legRestRot, sizingRatio, nbLegs

    BGL.glClearColor(0.55, 0.55, 0.55, 0.0)
    BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
    
    paintSectionTitle("Insect procedural walk - wibauxl - " + str(VERSION), X+1, Y + nbLegs.val*2*21 + 130, W-4)    
    
    # insect body definition
    paintSectionTitle("Insect body definition", X+1, Y + nbLegs.val*2*21 + 103, 125)    
    BGL.glColor3f(0.8,0.8,0.8)
    BGL.glRectf(X-4, Y, X+W, Y + nbLegs.val*2*21 + 98)
    BGL.glColor3f(0.0,0.0,0.0)    
    curY = Y + 5
    sizingRatio = Draw.Slider("Sizing ratio: ", 220, X+40, curY, 270, 19, sizingRatio.val, 0.1, 10.0, 0, "Overall sizing factor to apply to the above dimensions"); 
    curY += 10
    curY += 20 + nbLegs.val*21
    BGL.glRasterPos2i(X+60, curY); Draw.Text("Rot.R")
    BGL.glRasterPos2i(X+120, curY); Draw.Text("Rot.L")
    BGL.glRasterPos2i(X+189, curY); Draw.Text("Shadow.R")
    BGL.glRasterPos2i(X+252, curY); Draw.Text("Shadow.L")
    for n in range(nbLegs.val):
        BGL.glRasterPos2i(X, curY-(n+1)*20)
        Draw.Text("Leg " + str(n+1) + ":")
        legRestRot[RP][n] = Draw.Number("", 100+n, X+40, curY-3-(n+1)*21, 60, 18, legRestRot[RP][n].val, -180.0, 180.0, "Rest rotation for right leg")    
        legRestRot[LP][n] = Draw.Number("", 110+n, X+102, curY-3-(n+1)*21, 60, 18, legRestRot[LP][n].val, -180.0, 180.0, "Rest rotation for left leg")    
        legShadows[RP][n] = Draw.Number("", 120+n, X+188, curY-3-(n+1)*21, 60, 18, legShadows[RP][n].val, 0.0, 100.0, "Shadow length for right leg")    
        legShadows[LP][n] = Draw.Number("", 130+n, X+250, curY-3-(n+1)*21, 60, 18, legShadows[LP][n].val, 0.0, 100.0, "Shadow length for left leg")    
    curY += 20 + nbLegs.val*21
    BGL.glRasterPos2i(X+50, curY); Draw.Text("Start X")
    BGL.glRasterPos2i(X+111, curY); Draw.Text("Start Y")
    BGL.glRasterPos2i(X+173, curY); Draw.Text("Start Z")
    BGL.glRasterPos2i(X+246, curY); Draw.Text("Step height")
    for n in range(nbLegs.val):
        BGL.glRasterPos2i(X, curY-(n+1)*20)
        Draw.Text("Leg " + str(n+1) + ":")
        for i in range(3):
            legAtt[n][i] = Draw.Number("", 140+3*n+i, X+40+i*62, curY-3-(n+1)*21, 60, 18, legAtt[n][i].val, -100.0, 100.0, "Leg attachment position")
        legElev[n] = Draw.Number("", 150+n, X+250, curY-3-(n+1)*21, 60, 18, legElev[n].val, -100.0, 100.0, "Leg tip max height to the ground during step")
    curY += 23
    BGL.glRasterPos2i(X, curY); Draw.Text("Number of legs:")
    nbLegs = Draw.Menu("6 %x3|8 %x4", 3, X+102, curY-3, 60, 18, nbLegs.val)
    Draw.Button("Make symetrical", 10, X+190, curY-4, 120, 20, "Make left and right legs rest rotation and shadow length the same"); 
    
    # animation definition
    curY = Y-20
    paintSectionTitle("Animation", X+1, curY, 70)    
    BGL.glColor3f(0.8,0.8,0.8)
    BGL.glRectf(X-4, curY-5, X+W, curY-60)
    BGL.glColor3f(0.0,0.0,0.0)
    curY -= 26
    BGL.glRasterPos2i(X, curY+2); Draw.Text("Proxy:")
    proxyName = Draw.String("", 80, X+40, curY-4, 176, 19, proxyName.val, 64, "Name of the proxy")
    Draw.Button("Get selected", 11, X+220, curY-4, 90, 19, "Get the proxy name from the object currently selected")
    curY -= 24
    BGL.glRasterPos2i(X, curY+2); Draw.Text("Start:")
    startFrame = Draw.Number("", 3, X+40, curY-3, 50, 18, startFrame.val, 1, 10000, "Frame at which the walk starts")
    BGL.glRasterPos2i(X+115, curY+2); Draw.Text("End:")
    endFrame = Draw.Number("", 170, X+145, curY-3, 50, 18, endFrame.val, startFrame.val+1, 10000, "Frame at which the walk ends")
    BGL.glRasterPos2i(X+220, curY+2); Draw.Text("Step:")
    stepLength = Draw.Number("", 180, X+260, curY-3, 50, 18, stepLength.val, 2, 10000, "Number of frames required to perform a step")

    # Status and buttons
    curY = Y-88
    BGL.glColor3f(0.85,0.85,0.85)
    BGL.glRectf(X-4, curY, X+180, curY-20)
    BGL.glColor3f(0.0,0.0,0.9)
    BGL.glRasterPos2i(X+1, curY-14); 
    Draw.Text(msgString)
    Draw.Button("Run", 12, X+185, curY-19, 63, 19)
    Draw.Button("Exit", 1, X+252, curY-19, 63, 19)
    
def event(evt, val):    
    if (evt== Draw.ESCKEY and not val): Draw.Exit()

def bevent(evt):
    global msgString
    if   (evt== 1): Draw.Exit()
    elif (evt== 2): Draw.Redraw()
    elif (evt== 3): Draw.Redraw()
    elif (evt== 10): makeInsectSymetrical()
    elif (evt== 11):
        obj = Object.GetSelected()
        if obj != []: proxyName.val = obj[0].name
        else: 
            proxyName.val = ""
            msgString = "Got nothing"
        Draw.Redraw()
    elif (evt== 12): walkInsect()

Draw.Register(draw, event, bevent)


This is really interesting stuff… how about an example blender file and/or a youtube animation of a walking creature?

Hiya!

Just to be clear, this isn’t my script - just an old one I got working. As for an example, download the ant.blend here:

http://web.archive.org/web/20060717013643/http://perso.orange.fr/ml.wibaux/index.html

The results aren’t fantastic but I think that is more to do with the lack of proper IK constraints more than the script itself which works fine!

Just use the updated script and have fun! :slight_smile:

Koba