IC 8 Python API:End Effector Animation
- Main article: iC8 Python API.
In the production of character animation, FK and IK usually work in tandem to drive motion. Whereas iClone 7 was limited to FK animation, IK motion became a viable option in iClone 8. Generally speaking, FK animation is the manual rotation of each bone, while IK calculates bone rotations using the position and rotation of the end effector. IK can be used to effectively prevent motion sliding when characters come in contact with other objects or move on firm ground. In addition, the blend weights can be freely adjusted to favor FK or IK during the course of an animation. In terms of UI operation, you can operate the IK and FK settings through the Edit Motion Layer panel (as shown below).
For more information on IK/FK, see the iClone 7 Online Manual - What is IK_FK.
Same as iClone 7, you can use FK to control the pose of the character by rotating any skin bone. The usage of the Python API is roughly as follows:
1 transform_control = animation_clip.GetControl("Layer", any_bone)
2 transform_settings = transform_control.GetDataBlock() # Get data block
3 float_control = transform_settings.GetControl("Rotation/RotationX")
4
5 # add a key at frame 5
6 clip_time = RLPy.IndexedFrameTime(5, RLPy.RGlobal.GetFps())
7 float_control.SetValue(clip_time, float(math.radians(10)))
Or set the position of the end effector by controlling IK:
1 # Get Effector
2 l_foot = skeleton_component.GetEffector( RLPy.EHikEffector_LeftFoot )
3 effector_settings = clip.GetDataBlock( "Layer", l_foot )
4 float_control = effector_settings.GetControl("Position/PositionZ")
5 floor_z = 0.0
6 ret_list = float_control.GetValue(RLPy.RTime.FromValue(0), floor_z)
7 floor_z = ret_list[1]
8 print("lfoot z position is "+str(floor_z))
9
10 # add a key at frame 10
11 clip_time = RLPy.IndexedFrameTime(10, RLPy.RGlobal.GetFps())
12 float_control.SetValue(clip_time, floor_z+30)
You may find that using the gizmo to rotate the left foot, for example, has no effect since the foot IK is set to active by default. This is because IK override FK settings. You can overcome this limitation by setting the weight value for IK/FK or use RISkeletonComponent.BakeFkToIk() to convert FK rotation into IK positional data. The following code demonstrates this in practice:
1 transform_control = animation_clip.GetControl("Layer", l_foot_bone)
2 transform_settings = transform_control.GetDataBlock() # Get data block
3 float_control = transform_settings.GetControl("Rotation/RotationX")
4
5 # add a key at frame 5
6 set_time = RLPy.IndexedFrameTime(5, RLPy.RGlobal.GetFps())
7 float_control.SetValue(set_time, float(math.radians(10)))
8 clip_time = animation_clip.ClipTimeToSceneTime(set_time)
9 skeleton_component.BakeFkToIk(clip_time, False)
10 # False will do FK to IK only at clip_time.
11 # if True, will apply to all time ranges of the clip.