Source code for splib.animation.animate

# -*- coding: utf-8 -*-
import Sofa
from splib.utils import deprecated_alias

class Animation(object):
    """An animation clip that trigger callback at regular intervales for a given duration.

           :param mode: specify how the animation will continue (None, "loop", "pingpong")
           :param duration: the duration of the animation in seconds.
           :param onUpdate: callback function called each update.
           :param onDone: callback function called when the animation is terminated.
           :param params: a dictionnary with user specified extra parameters that are passed to the callback.

    Example of use:


    .. code-block:: python

        def createScene(rootNode):
            AnimationManager(rootNode)

            def onUpdate(target, factor):
                print("Callback called on: "+target.name+" factor is: "+str(factor))

            def onDone(target, factor):
                print("Callback when animation is done: "+target.name+" factor is: "+str(factor))

            animate(onUpdate, {"target" : rootNode }, 12, onDone=onDone)
    """
    @deprecated_alias(cb='onUpdate')
    def __init__(self, duration, mode, onUpdate, params, onDone=None):
        if 'startTime' in params:
            self.startTime = params['startTime']
        else:
            self.startTime = None

        self.duration = duration
        self.onUpdate = onUpdate        
        self.onDone = onDone
        self.params = params
        self.factor = 1.0
        self.direction = 1.0
        self.mode = mode

    def doOnDone(self, currentTime):
        self.onDone(factor=self.factor, **self.params)

    def update(self, currentTime):
        if self.startTime is None:
            self.startTime = currentTime

        if self.duration == 0.0:
            self.factor = 1.0
        elif self.direction > 0.0:
            self.factor = (currentTime-self.startTime) / self.duration
        else:
            self.factor = 1.0-(currentTime-self.startTime) / self.duration

        if self.factor > 1.0:
            self.factor = 1.0

        if self.factor < 0.0:
            self.factor = 0.0

        self.onUpdate(factor=self.factor, **self.params)


class AnimationManagerController(Sofa.PythonScriptController):
    """Implements the AnimationManager as a PythonScriptController
    """
    def __init__(self, node):
        self.listening = True
        self.name = "AnimationManager"
        self.totalTime = 0
        self.animations = []

    def addAnimation(self, animation):
        self.animations.append(animation)

    def removeAnimation(self, animation):
        self.animations.remove(animation)

    def bwdInitGraph(self, root):
        self.onBeginAnimationStep(0.0)

    def onBeginAnimationStep(self, dt):
        self.totalTime += dt
        nextanimations = []
        for animation in self.animations:
            animation.update(self.totalTime)
            if animation.factor < 1.0 and animation.direction > 0.0:
                nextanimations.append(animation)
            elif animation.factor > 0.0 and animation.direction < 0.0:
                nextanimations.append(animation)
            elif animation.mode == "pingpong":
                animation.direction = -animation.direction
                animation.startTime = None
                nextanimations.append(animation)
            elif animation.mode == "loop":
                animation.direction = animation.direction
                animation.startTime = None
                nextanimations.append(animation)
            elif animation.onDone is not None:
                animation.doOnDone(self.totalTime)
        self.animations = nextanimations
        return 0


manager = None

[docs]def animate(onUpdate, params, duration, mode="once", onDone=None): """Construct and starts an animation Build a new animation from a callback function that computes the animation value, a set of parameters, the animation duration and the type of animation repetition pattern. Animation can be added from any code location (createScene, PythonScriptController) :param float duration: duration of the animation in seconds. :param str mode: once, loop, pingpong Example: .. sourcecode:: python def myAnimate(target, factor): print("I should do something on: "+target.name) def createScene(rootNode) AnimationManager(rootNode) animate(myAnimate, {"target" : rootNode }, 10) """ if manager == None: raise Exception("Missing manager in this scene") manager.addAnimation(Animation(duration=duration, mode=mode, onUpdate=onUpdate, params=params, onDone=onDone))
def removeAnimation(animation): if manager == None: raise Exception("Missing manager in this scene") manager.removeAnimation(animation)
[docs]def AnimationManager(node): """ A Controller to manage all animations in the scene Before using the animation framework an AnimationManager must be added to the scene. It has in charge, at each time step to update all the running animations. Returns: AnimationManagerController Example: .. sourcecode:: python def createScene(rootNode) AnimationManager(rootNode) """ global manager if manager is not None: Sofa.msg_info(node, "There is already one animation manager in this scene...why do you need a second one ?") return manager manager = AnimationManagerController(node) return manager
# This function is just an example on how to use the animate function. def createScene(rootNode): def myAnimate1(target, factor): print("I should do something on: "+target.name+" factor is: "+str(factor)) def myAnimate2(target, factor): print("Function 2: "+target.name+" factor is: "+str(factor)) def myOnDone(target, factor): print("onDone: "+target.name+" factor is: "+str(factor)) AnimationManager(rootNode) animate(myAnimate1, {"target": rootNode}, 10) animate(myAnimate2, {"target": rootNode}, 12, onDone=myOnDone)