PandaSteer 2

I’ve been playing around with animations switch. I think synchronizing the next anim’s start frame to the current one’s frame must help to avoid sudden weird body parts movement, especially the legs. No blending here, so it’s still rough.
And I tried playing the walk anim when switching to stand pose, instead of simply posing the actor. The start frame uses the walk anim’s current frame, but “mirrored” relative to the middle of the anim’s number of frames. It’s to get the start frame for the shortest anim length to the stand pose frame (i.e. frame 6 for ralph, as you’ve used since the beginning), while maintaining body parts’ position as close as possible to the current walk frame.

To get the most acceptable result, I switched it to stand pose after the velocity length went below .05. Less than that, the actor will slide for a while (due to small playrate) before playing the anim.

    def storeLastPose(self):
        currAnim=self.actor.getCurrentAnim()
        numFrames=self.actor.getNumFrames(currAnim)
        animFrame=self.actor.getCurrentFrame(currAnim)
        self.lastPose=float(animFrame)/float(numFrames)
        self.actor.stop(currAnim)
        #print currAnim, self.lastPose

    def loopFromPose(self,animName):
        self.actor.pose(animName, frame=self.lastPose*self.actor.getNumFrames(animName))
        self.actor.loop(animName, restart=0)

    # FSM State handlers. Called when transitioning to a new state.
    def enterRun(self):  self.loopFromPose("run")
    def exitRun(self):   self.storeLastPose()
    def enterWalk(self): self.loopFromPose("walk")
    def exitWalk(self):  self.storeLastPose()
    def enterStand(self):
        standPoseFrame=6    # frame 6 (the most acceptable stand pose)
        numFrames=self.actor.getNumFrames("walk")
        lastFrame=self.lastPose*numFrames
        # "mirror" the frame to bring it closer to the most acceptable stand pose
        if lastFrame>.5*(numFrames-1):
           lastFrame=numFrames-1-lastFrame
        #----------------------------------------------
        frameDiff=standPoseFrame-lastFrame
        # if already at stand pose, don't do anything
        if frameDiff==0:
           return
        # forward animation playback
        if frameDiff>=0:
           fromFrame=lastFrame
           toFrame=standPoseFrame
        else:
        # backward animation playback
           fromFrame=standPoseFrame
           toFrame=lastFrame
        #----------------------------------------------
        playDir=2*frameDiff/numFrames
        self.actor.setPlayRate(playDir,"walk")
        self.actor.play("walk", fromFrame=fromFrame, toFrame=toFrame)
        #print 'switch to stand pose'