I don't think this helps you answer your 'What you are trying to do', but as far as the question of what are the other overrides for GetControl?
I don't know the complete list either, but I searched my Python folder by text and found this class which is by Reallusion I think (I know I didn't write it).
It shows a few examples with layer, and Position/PositionX, Y and Z and RotationX, Y and Z, so it looks like some properties are exposed via GetControl.
It would be nice to know all the options.
import RLPy
source_Avatar_name = "1.Base Female"
target_Avatar_name = "1.Base Female(0)"
clip_step = 1
isMirror = True
def get_bone_transform(bone):
data = {}
local_transform = bone.LocalTransform()
local_translation = local_transform.T()
local_rotation = local_transform.R()
data["r"] = [local_rotation.x, local_rotation.y, local_rotation.z, local_rotation.w] # Bone Rotations
data["t"] = [local_translation.x, local_translation.y, local_translation.z] # Bone Translations
return data
def set_bone_transform(animation_clip, bone, time, pose, offset, mirror=False, isRootBone=False):
bone_control = animation_clip.GetControl("Layer", bone)
data_block = bone_control.GetDataBlock()
q_pose = RLPy.RQuaternion(RLPy.RVector4(pose["r"][0], pose["r"][1], pose["r"][2], pose["r"][3]))
q_offset = RLPy.RQuaternion(RLPy.RVector4(offset["r"][0], offset["r"][1], offset["r"][2], offset["r"][3]))
q_real = q_pose.Multiply(q_offset.Inverse())
m_real = q_real.ToRotationMatrix()
x = y = z = 0
r_real = m_real.ToEulerAngle(RLPy.EEulerOrder_XYZ, x, y, z)
data_block.GetControl("Rotation/RotationX").SetValue(time, r_real[0])
data_block.GetControl("Rotation/RotationY").SetValue(time, r_real[1] if mirror is False else -r_real[1])
data_block.GetControl("Rotation/RotationZ").SetValue(time, r_real[2] if mirror is False else -r_real[2])
if data_block.GetControl("Position/PositionX") is not None:
if isRootBone is True:
moveX = pose["t"][0]
moveY = pose["t"][1]
moveZ = pose["t"][2]
if mirror is True:
#moveX = moveX - offset["t"][0]
moveX = - moveX
data_block.GetControl("Position/PositionX").SetValue(time, moveX)
data_block.GetControl("Position/PositionY").SetValue(time, moveY)
data_block.GetControl("Position/PositionZ").SetValue(time, moveZ)
else:
data_block.GetControl("Position/PositionX").SetValue(time, pose["t"][0] - offset["t"][0])
data_block.GetControl("Position/PositionY").SetValue(time, pose["t"][1] - offset["t"][1])
data_block.GetControl("Position/PositionZ").SetValue(time, pose["t"][2] - offset["t"][2])
source_Avatar = RLPy.RScene.FindObject(RLPy.EObjectType_Avatar, source_Avatar_name)
target_Avatar = RLPy.RScene.FindObject(RLPy.EObjectType_Avatar, target_Avatar_name)
source_Avatar_SC = source_Avatar.GetSkeletonComponent()
target_Avatar_SC = target_Avatar.GetSkeletonComponent()
source_Clip = source_Avatar_SC.GetClip(0)
source_Clip_Len = source_Clip.GetLength()
total_Clip_Frames = int(source_Clip_Len.GetValue()/1000*60)
scene_End = source_Clip.ClipTimeToSceneTime(source_Clip_Len)
clip_Last_Frame = int(scene_End.GetValue()/1000*60)
clip_First_Frame = clip_Last_Frame - total_Clip_Frames
source_motion_bones = source_Avatar_SC.GetMotionBones()
source_root_bone = source_Avatar_SC.GetRootBone()
target_motion_bones = target_Avatar_SC.GetMotionBones()
target_root_bone = target_Avatar_SC.GetRootBone()
for clipFrame in range(clip_First_Frame, clip_Last_Frame + 1, clip_step):
clip_time = RLPy.RTime.IndexedFrameTime(1, RLPy.RGlobal.GetFps())
RLPy.RGlobal.SetTime(RLPy.RTime.IndexedFrameTime(clipFrame, RLPy.RGlobal.GetFps()))
current_time = RLPy.RGlobal.GetTime()
frame_source_pose = {}
frame_target_pose = {}
for bone in source_motion_bones:
frame_source_pose[bone.GetName()] = get_bone_transform(bone)
frame_source_pose[source_root_bone.GetName()] = get_bone_transform(source_root_bone)
inverted_Clip = target_Avatar_SC.AddClip(RLPy.RGlobal.GetTime())
target_Avatar.Update()
if isMirror == True:
for bone in target_motion_bones:
name = bone.GetName()
frame_target_pose[name] = get_bone_transform(bone)
for bone in target_motion_bones:
name = bone.GetName()
opposite_side = ""
if "_L_" in name:
opposite_side = name.replace("_L_", "_R_")
if "_R_" in name:
opposite_side = name.replace("_R_", "_L_")
if opposite_side in frame_source_pose:
set_bone_transform(inverted_Clip, bone, clip_time, frame_source_pose[opposite_side], frame_target_pose[opposite_side], True, False)
else:
set_bone_transform(inverted_Clip, bone, clip_time, frame_source_pose[name], frame_target_pose[name], True, False)
target_data = get_bone_transform(target_root_bone)
rname = target_root_bone.GetName()
set_bone_transform(inverted_Clip, target_root_bone, clip_time, frame_source_pose[rname], target_data, True, True)
else:
for bone in target_motion_bones:
name = bone.GetName()
target_data = get_bone_transform(bone)
set_bone_transform(inverted_Clip, bone, clip_time, frame_source_pose[name], target_data, False, False)
target_data = get_bone_transform(target_root_bone)
rname = target_root_bone.GetName()
set_bone_transform(inverted_Clip, target_root_bone, clip_time, frame_source_pose[rname], target_data, False, True)
RLPy.RGlobal.ObjectModified(target_Avatar, RLPy.EObjectModifiedType_Transform)
I watched my first intro video into Python for Blender a couple of days ago, and Reallusion has so much to catch up.
Blender has 'Intellisense' type help that lets you know all the properties and methods available for each option. With IClone I have felt like everything has been a hunt to find. This is why I wish the Python API was open source, so we could go look at the code and write new code if needed.
Just wanted to subscribe to this in case anyone answers it.
Creator of the free website:
PixelDatabase.Net
A Free Online Text Based Image Editor