Source code for mor.animation.shakingAnimations

# -*- coding: utf-8 -*-
"""
Implemented animation functions
"""
from math import cos
from math import sin

[docs] def upDateValue(actualValue,actuatorMaxPull,actuatorIncrement): """ Utility function for default animation. Increment a sofa data value until fixed amount :param actualValue: :param actuatorMaxPull: :param actuatorIncrement: :return: actualValue : """ if actualValue < actuatorMaxPull: print ("INCREMENT ++") return actualValue + actuatorIncrement else: print ("Done") return actualValue
[docs] def rotationPoint(Pos0, angle, brasLevier): """ Utility function applying rotation on a given position with some lever arm :param Pos0: :param angle: :param brasLevier: :return: New updated position """ print ("In rotation POint") size0 = len(Pos0); posOut = [] for i in range(size0): posOut.append([Pos0[i][0]- brasLevier*cos(angle), Pos0[i][1] - brasLevier*sin(angle), Pos0[i][2]]) print(posOut) return posOut
lastTime = 0
[docs] def defaultShaking( objToAnimate, dt, factor, **param): """ **Default animation function** The animation consist on *increasing* a value of a Sofa object until it reach its *maximum* To use it the **params** parameters of :py:class:`.ObjToAnimate` which is a dictionnary will need 4 keys: **Keys:** +---------------+-------+---------------------------------------------------------------------------------+ | argument | type | definition | +===============+=======+=================================================================================+ | dataToWorkOn | str | Name of the Sofa datafield we will work on by default it will be set to *value* | +---------------+-------+---------------------------------------------------------------------------------+ | incrPeriod | float | Period between each increment | +---------------+-------+---------------------------------------------------------------------------------+ | incr | float | Value of each increment | +---------------+-------+---------------------------------------------------------------------------------+ | rangeOfAction | float | Until which value the data will increase | +---------------+-------+---------------------------------------------------------------------------------+ :return: None """ import Sofa global lastTime writeCurrent = False time = factor * objToAnimate.duration period = dt * objToAnimate.params['incrPeriod'] argList = ['dataToWorkOn','incrPeriod','incr','rangeOfAction'] if not all(objToAnimate.params["dataToWorkOn"]): raise('Missing parameter') else: if (time == dt): writeCurrent = True if (time-(lastTime + period + dt) >= 0.000001): # (time > (lastTime + period + dt)): lastTime += period if ( abs(time-(lastTime + period + dt)) <= 0.000001 ): writeCurrent = True if (writeCurrent): print("For Actuator : "+objToAnimate.location) actualValue = objToAnimate.item.findData(objToAnimate.params["dataToWorkOn"]).value[0]#[0] actualValue = upDateValue(actualValue,objToAnimate.params['rangeOfAction'],objToAnimate.params['incr']) objToAnimate.item.findData(objToAnimate.params["dataToWorkOn"]).value = [float(actualValue)] print ("Updated Value :"+str(actualValue)+'\n')
[docs] def doingCircle( objToAnimate, dt, factor, **param): """ **Animation function made specifically to apply deformation on the liver scene.** It's an example of what can be a custom shaking animation. The animation consist on taking a position in entry, rotate it, and then update it in the component. To use it the **params** parameters of :py:class:`.ObjToAnimate` which is a dictionnary will need 6 keys: **Keys:** +---------------+-------+-----------------------------------------------------------------------+ | argument | type | definition | +===============+=======+=======================================================================+ | dataToWorkOn | str | Name of the Sofa datafield we will work on here it will be *position* | +---------------+-------+-----------------------------------------------------------------------+ | incrPeriod | float | Period between each increment | +---------------+-------+-----------------------------------------------------------------------+ | incr | float | Value of each increment | +---------------+-------+-----------------------------------------------------------------------+ | rangeOfAction | float | Until which value the data will increase | +---------------+-------+-----------------------------------------------------------------------+ | angle | float | Initial angle value in radian | +---------------+-------+-----------------------------------------------------------------------+ | rodRadius | float | Radius Lenght of the circle | +---------------+-------+-----------------------------------------------------------------------+ """ moduloResult = int( round( (factor * objToAnimate.duration)*1000 ) ) % int( dt * objToAnimate.params['incrPeriod']*1000 ) # print("currentTime - startTime : "+str(factor * objToAnimate.duration)) if moduloResult == 0: currentPositions = objToAnimate.item.findData(objToAnimate.params["dataToWorkOn"]).value objToAnimate.params['angle'] = upDateValue( objToAnimate.params['angle'], objToAnimate.params['rangeOfAction'], objToAnimate.params['incr']) with objToAnimate.item.position.writeable() as positions: newPositions = rotationPoint(positions, -objToAnimate.params['angle'], objToAnimate.params['rodRadius']) for i in range(len(positions)): positions[i] = newPositions[i]
[docs] def shakingInverse( objToAnimate, dt, factor, **param): """ **Animation function to use with iinverse simulation** """ moduloResult = int( round( (factor * objToAnimate.duration)*1000 ) ) % int( dt * objToAnimate.params['incrPeriod']*1000 ) if moduloResult == 0: print("For Actuator : "+objToAnimate.location) actualValue = objToAnimate.obj.findData(objToAnimate.params["dataToWorkOn"]).value[objToAnimate.params["goalNbr"]] actualValue = upDateValue(actualValue,objToAnimate.params['rangeOfAction'],objToAnimate.params['incr']) objToAnimate.obj.findData(objToAnimate.params["dataToWorkOn"]).value[objToAnimate.params["goalNbr"]] = actualValue print ("Updated Value :"+str(actualValue)+'\n')
[docs] def doingNothing( objToAnimate, dt, factor, **param): """ **Default animation function** The animation consist on *increasing* a value of a Sofa object until it reach its *maximum* To use it the **params** parameters of :py:class:`.ObjToAnimate` which is a dictionnary will need 4 keys: **Keys:** +---------------+-------+---------------------------------------------------------------------------------+ | argument | type | definition | +===============+=======+=================================================================================+ | dataToWorkOn | str | Name of the Sofa datafield we will work on by default it will be set to *value* | +---------------+-------+---------------------------------------------------------------------------------+ | incrPeriod | float | Period between each increment | +---------------+-------+---------------------------------------------------------------------------------+ | incr | float | Value of each increment | +---------------+-------+---------------------------------------------------------------------------------+ | rangeOfAction | float | Until which value the data will increase | +---------------+-------+---------------------------------------------------------------------------------+ :return: None """ global lastTime writeCurrent = False time = factor * objToAnimate.duration period = dt * objToAnimate.params['incrPeriod'] if (time == dt): writeCurrent = True if (time-(lastTime + period + dt) >= 0.000001): # (time > (lastTime + period + dt)): lastTime += period if ( abs(time-(lastTime + period + dt)) <= 0.000001 ): writeCurrent = True if (writeCurrent): print ("Doing Nothing")