From 7736a4b143a8fdbb07150322028f641526d43e3d Mon Sep 17 00:00:00 2001 From: Adabriand Furtado Date: Tue, 18 Aug 2015 17:33:39 -0300 Subject: [PATCH] Integração do movimento de contato ao novo modelo JSON --- avatar_cartoon_v2.74.blend | Bin 6986320 -> 0 bytes decode.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ facial.py | 18 ++++++------------ libras.py | 132 +++++++++++++++++++----------------------------------------------------------------------------------------------------------------- moves.py | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------- util.py | 70 ++++++++++++++++++++++++---------------------------------------------- 6 files changed, 174 insertions(+), 263 deletions(-) create mode 100644 decode.py diff --git a/avatar_cartoon_v2.74.blend b/avatar_cartoon_v2.74.blend index 1e1befe..c985beb 100755 Binary files a/avatar_cartoon_v2.74.blend and b/avatar_cartoon_v2.74.blend differ diff --git a/decode.py b/decode.py new file mode 100644 index 0000000..13b28da --- /dev/null +++ b/decode.py @@ -0,0 +1,54 @@ +import moves +import util + +def circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular): + # const + dict_ray = {'pequeno': 0.5, 'normal': 1.0, 'grande': 1.5} + dict_period = {'lento': 55, 'normal': 45, 'rapido': 35} + # decodificar valores + ray = dict_ray[js_movement['raio']] + period = dict_period[js_movement['velocidade']] + #print('setar articulacao:', js_movement['articulacao']) + #print('setar configuracao:', js_movement['configuracao']) + #print('setar orientacao:', js_movement['orientacao']) + # diminuir a velocidade + if (js_movement['velocidade'] == 'lento'): + period += 10 + # aumentar a velocidade + elif (js_movement['velocidade'] == 'rapido'): + period -= 10 + # definir eixos do movimento + if (js_movement['plano'] == 'frente-esquerda'): + x, y = 2, 0 + elif (js_movement['plano'] == 'frente-cima'): + x, y = 2, 1 + else: + x, y = 0, 1 + # mao usada (direita/esquerda) + if (is_right_hand): + ik = bpy.context.object.pose.bones['ik_FK.R'] + else: + ik = bpy.context.object.pose.bones['ik_FK.L'] + current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location']) + current_frame = moves.circular(ik, current_frame + frame_jump, ray, period, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular) + return current_frame + +def contato(js_movement, current_frame, frame_jump, is_right_hand): + sub_type = next(iter(js_movement.keys())) + mov_param = js_movement[sub_type] + action = util.right_hand_actions if is_right_hand else util.left_hand_actions + bones = util.rightBonesConf if is_right_hand else util.leftBonesConf + current_frame = current_frame + 2*frame_jump + return moves.contato(action, sub_type, mov_param, bones, current_frame, frame_jump) + +def hand_mov(current_frame, frame_jump, js_mao, is_right_hand): + if (js_mao == {}): + return + movement_name = next(iter(js_mao.keys())) + if (movement_name == 'circular'): + current_frame = circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, False) + elif (movement_name == 'semicircular'): + current_frame = circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True) + elif (movement_name == 'contato'): + current_frame = contato(js_mao[movement_name], current_frame, frame_jump, is_right_hand) + return current_frame + frame_jump \ No newline at end of file diff --git a/facial.py b/facial.py index 1f32a4b..3172c7c 100644 --- a/facial.py +++ b/facial.py @@ -3,8 +3,6 @@ import bpy import util -library_name = '07_facial' - # duracao na posicao selecionada dict_duration = { 'lento': 15, @@ -19,9 +17,6 @@ dict_transition = { 'rapido': 5 } -# marcador global da linha do tempo exclusivo para expressao facial -timeline_facial = 0 - # insere keyframes aos bones selecionados anteriormente e passados como parametro def keyframe_insert(current_frame = 0, pose_bones = bpy.context.object.pose.bones, keyframe_types = ['location', 'rotation_quaternion']): # verifica se existe apenas um bone @@ -64,9 +59,8 @@ def apply_pose(index = 0, pose_library = list(bpy.data.actions)): return # consolida o movimento (faz insercao dos keyframes) e incrementa a timeline -def set_expression(index, frame_duration = dict_duration['normal'], frame_transition = 0): - global timeline_facial - global library_name +def set_expression(timeline_facial, index, frame_duration = dict_duration['normal'], frame_transition = 0): + library_name = util.facial_expression_id bones_facial = util.dict_bones[library_name] util.select_bones(bones_facial) # TODO separar bones 'location' e 'rotation_quaternion' @@ -81,7 +75,7 @@ def set_expression(index, frame_duration = dict_duration['normal'], frame_transi return timeline_facial # decodifica objeto JSON -def decode_expression(js_facial, initial_interpolation = dict_duration['normal']): +def decode_expression(timeline_facial, js_facial, initial_interpolation = dict_duration['normal']): global dict_duration global dict_transition index = js_facial['expressao'] @@ -89,9 +83,9 @@ def decode_expression(js_facial, initial_interpolation = dict_duration['normal'] frame_transition = dict_duration[js_facial['transicao']] # insere o primeiro keyframe if (timeline_facial == 0): - set_expression(0, initial_interpolation) - set_expression(index, frame_duration, frame_transition) - set_expression(0, frame_duration) + set_expression(timeline_facial, 0, initial_interpolation) + set_expression(timeline_facial, index, frame_duration, frame_transition) + set_expression(timeline_facial, 0, frame_duration) return timeline_facial """ diff --git a/libras.py b/libras.py index 6c1f9f0..0e34502 100644 --- a/libras.py +++ b/libras.py @@ -19,13 +19,14 @@ import util import moves import pyutil import facial +import decode # intervalos de interpolacao dos keyframes dict_interpolation = { 'inicial': 20, - 'lento': 5, + 'lento': 15, 'normal': 10, - 'rapido': 15, + 'rapido': 5, 'final': 20 } @@ -33,108 +34,18 @@ def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones = for obj in (pose_bones): obj.bone.select = True for type_keyframe in types_keyframe: - obj.keyframe_insert(index = -1, frame = current_frame, group = obj.name, data_path = type_keyframe) + util.keyframe_insert(obj, type_keyframe, current_frame, False) obj.bone.select = False - return current_frame + frame_jump + return current_frame def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions): - result = 0 + result = current_frame for action in actions: if (action.use_fake_user): bpy.context.object.pose_library = action bpy.ops.poselib.apply_pose(pose_index = 0) result = insert_keyframe_pose_default(current_frame, frame_jump) - return result - -def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular): - # const - dict_ray = {'pequeno': 0.5, 'normal': 1.0, 'grande': 1.5} - dict_period = {'lento': 55, 'normal': 45, 'rapido': 35} - # decodificar valores - ray = dict_ray[js_movement['raio']] - period = dict_period[js_movement['velocidade']] - print('setar articulacao:', js_movement['articulacao']) - print('setar configuracao:', js_movement['configuracao']) - print('setar orientacao:', js_movement['orientacao']) - # diminuir a velocidade - if (js_movement['velocidade'] == 'lento'): - period += 10 - # aumentar a velocidade - elif (js_movement['velocidade'] == 'rapido'): - period -= 10 - # definir eixos do movimento - if (js_movement['plano'] == 'frente-esquerda'): - x, y = 2, 0 - elif (js_movement['plano'] == 'frente-cima'): - x, y = 2, 1 - else: - x, y = 0, 1 - # mao usada (direita/esquerda) - if (is_right_hand): - ik = bpy.context.object.pose.bones['ik_FK.R'] - else: - ik = bpy.context.object.pose.bones['ik_FK.L'] - current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location']) - current_frame = moves.circular(ik, current_frame + frame_jump, ray, period, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular) - return current_frame - -def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand): - if (js_mao == {}): - return - movement_name = next(iter(js_mao.keys())) - print("Movimento: " + movement_name) - if (movement_name == 'circular'): - current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, False) - elif (movement_name == 'semicircular'): - current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True) - return current_frame + frame_jump - -""" -# Funcao responsavel por setar pose padrao -def poseDefault(json_input, positionFrames, collisionFlag = False): - handDefaultParam = [0, 0, 0] - util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag) - if(json_input["leftHand"] != []): - util.setPose(util.left_hand_actions, handDefaultParam, positionFrames, util.leftBonesConf, collisionFlag) - setFaceConfiguration([0], positionFrames, util.faceBonesConf) - -# Funcao responsavel por setar as configuracoes das maos -def setHandConfiguration(actions, handParam, positionFrames, bones): - util.setPose(actions, handParam, positionFrames, bones) - -# Funcao responsavel por setar a configuracao da face -def setFaceConfiguration(handParam, positionFrames, bones): - util.setPose(util.facial_expression_action, handParam, positionFrames, bones) - -#Funcao que inicia a configuracao de ambas as maos -def configureHands(endFrame): - # Array com valores dos campos que serao passados pelo JSON - hands = ["rightHand", "leftHand"] - iks = ["ik_FK.R", "ik_FK.L"] - bones_ = [util.rightBonesConf, util.leftBonesConf] - # Array com as actions FAKES que seram selecionadas no Blender para cada lado do corpo - actions = [util.right_hand_actions, util.left_hand_actions] - for i in range(len(hands)): - if(json_input[hands[i]] != []): - move = json_input[hands[i]][0] - pose = util.armature.pose.bones[iks[i]] - handParam = json_input[hands[i]][-3:] - if(move in ["pontual", "circular", "semicircular", "retilineo", "senoidal"]): - setHandConfiguration(actions[i], handParam, util.hands_default_frames, bones_[i]) - if(move in ["circular", "semicircular"]): - orientation, direction, radius, laps = json_input[hands[i]][1:5] - #endFrame = moves.circular_or_semiCircular(pose, orientation, direction, radius, laps, 5) - setHandConfiguration(actions[i], handParam, [endFrame], bones_[i]) - elif(move == "retilineo"): - setHandConfiguration(actions[i], json_input[hands[i]][-6:-3], util.hands_default_frames, bones_[i]) - setHandConfiguration(actions[i], handParam, util.hands_frames_retilineo, bones_[i]) - elif(move == "senoidal"): - orientation, direction, radius, laps = json_input[hands[i]][1:5] - #endFrame = circular_or_semiCircular(pose, orientation, direction, radius, laps, 5) - setHandConfiguration(actions[i], handParam, [endFrame], bones_[i]) - elif(move == "contato"): - endFrame = moves.contato(actions[i], json_input[hands[i]], bones_[i], pose) -""" + return result + frame_jump def main(): util.delete_all_keyframes() @@ -147,11 +58,14 @@ def main(): frame_jump = dict_interpolation[js_input['interpolacao']] endFrame = pose_default(0) - mao_esquerda_frame = 0 - mao_direita_frame = 0 + timeline_mao_esquerda = 0 + timeline_mao_direita = 0 + timeline_facial = 0 - # pose padrao inicial em todos os bones ('location' e 'rotation_quaternion') + # setar pose padrao inicial em todos os bones ('location' e 'rotation_quaternion') endFrame += pose_default(dict_interpolation['inicial']) + timeline_mao_esquerda = endFrame + timeline_mao_direita = endFrame for i in range(0, len(js_movimentos)): # tenta decodificar objetos JSON @@ -171,35 +85,27 @@ def main(): # faz tratamento dos objetos if (js_facial == {}): pyutil.log(" js_movimentos[%d] >> Exp facial" % (i)) - facial.set_expression(0, facial.timeline_facial + frame_jump) + timeline_facial = facial.set_expression(timeline_facial, 0) else: - facial.decode_expression(js_facial) + timeline_facial = facial.decode_expression(timeline_facial, js_facial) if (js_mao_esquerda == {}): pyutil.log(" js_movimentos[%d] >> Mao esquerda" % (i)) # TODO posicionar mao esquerda na lateral do corpo else: - mao_esquerda_frame += decode_hand_mov(mao_esquerda_frame, frame_jump, js_mao_esquerda, False) + timeline_mao_esquerda = decode.hand_mov(timeline_mao_esquerda, frame_jump, js_mao_esquerda, False) if (js_mao_direita == {}): pyutil.log(" js_movimentos[%d] >> Mao direita" % (i)) # TODO posicionar mao direita na lateral do corpo else: - mao_direita_frame += decode_hand_mov(mao_direita_frame, frame_jump, js_mao_direita, True) + timeline_mao_direita = decode.hand_mov(timeline_mao_direita, frame_jump, js_mao_direita, True) - endFrame = max(facial.timeline_facial, mao_esquerda_frame, mao_direita_frame) + endFrame = max(timeline_facial, timeline_mao_esquerda, timeline_mao_direita) endFrame += frame_jump # setar pose padrao final em todos os bones (location e rotation) - #endFrame += pose_default(endFrame + dict_interpolation['final']) - #endFrame = insert_keyframe_pose_default(endFrame, frame_jump) - #endFrame += dict_interpolation['final'] - #endFrame = util.get_endFrame(js_input, util.hands_frames_retilineo) - #poseDefault([1]) - #configureHands(endFrame) - #configureFace(endFrame) - #poseDefault(js_input, [endFrame + 15]) - + endFrame += pose_default(endFrame + dict_interpolation['final']) util.render_sign(js_input["userId"], js_input["sinal"], endFrame) except: diff --git a/moves.py b/moves.py index ad29072..5f354c5 100644 --- a/moves.py +++ b/moves.py @@ -3,148 +3,127 @@ import bpy import math import util +import pyutil -def contato(action, input_hand, bones, pose, initialFrame = 18): - currentFrame = initialFrame - contact_type = input_hand[1] +def read_hand_param(mov_param): + conf_param = mov_param['configuracao'] if 'configuracao' in mov_param else 0 + artic_param = mov_param['articulacao'] if 'articulacao' in mov_param else 0 + orient_param = mov_param['orientacao'] if 'orientacao' in mov_param else 0 + return [conf_param, artic_param, orient_param] +def contato(action, contact_type, mov_param, bones, initialFrame = 18, frameJump = 10): if (contact_type == "alisar"): - currentFrame = alisar(action, input_hand, pose, bones, initialFrame) + currentFrame = alisar(action, mov_param, bones, initialFrame, frameJump) elif (contact_type == "cocar"): - currentFrame = cocar(action, input_hand, bones, initialFrame) + currentFrame = cocar(action, mov_param, bones, initialFrame, frameJump) elif (contact_type == "tocar"): - currentFrame = tocar(action, input_hand, bones, initialFrame) + currentFrame = tocar(action, mov_param, bones, initialFrame, frameJump) elif (contact_type == "riscar"): - currentFrame = riscar(action, input_hand, bones, initialFrame) + currentFrame = riscar(action, mov_param, bones, initialFrame, frameJump) return currentFrame -def riscar(action, input_hand, bones, pose, initialFrame = 18, bnAntBracoDegree = 2, bnMaoDegree = 45, frameJump = 10): +def riscar(action, mov_param, bones, initialFrame = 25, frameJump = 10, bnAntBracoDegree = 2, bnMaoDegree = 45): currentFrame = initialFrame - endFrame = initialFrame + 2 * frameJump - handParam = input_hand[-3:] + handParam = read_hand_param(mov_param) lado = "R" if util.rightBonesConf == bones else "L" - bnAntBraco = bpy.context.object.pose.bones["BnAntBraco." + lado] - bnAntBraco.bone.select = True - util.apply_rotation(bnAntBraco, "Z", currentFrame, endFrame, bnAntBracoDegree) - currentFrame += frameJump - util.apply_rotation(bnAntBraco, "Z", currentFrame, endFrame, (-1)*(bnAntBracoDegree+1)) - bnAntBraco.bone.select = False + #bnAntBraco = bpy.context.object.pose.bones["BnAntBraco." + lado] + #util.apply_rotation(bnAntBraco, "Z", currentFrame, bnAntBracoDegree) + #currentFrame += frameJump + #util.apply_rotation(bnAntBraco, "Z", currentFrame, (-1)*(bnAntBracoDegree+1)) currentFrame = initialFrame util.setPose(action, handParam, [currentFrame], bones) bnMao = bpy.context.object.pose.bones["BnMao." + lado] - bnMao.bone.select = True - util.apply_rotation(bnMao, "Y", currentFrame, endFrame, bnMaoDegree) currentFrame += frameJump - util.apply_rotation(bnMao, "Y", currentFrame, endFrame, (-2)*bnMaoDegree) - currentFrame += frameJump - util.apply_rotation(bnMao, "Y", currentFrame, endFrame, bnMaoDegree) - util.setPose(action[0:2], handParam[0:2], [currentFrame], bones) + util.apply_rotation(bnMao, "Y", currentFrame, bnMaoDegree) + currentFrame += int(frameJump/2) + util.apply_rotation(bnMao, "Y", currentFrame, (-1)*bnMaoDegree) + currentFrame += int(frameJump/2) + util.apply_rotation(bnMao, "Y", currentFrame, (-2)*bnMaoDegree) currentFrame += frameJump - bnMao.bone.select = False + util.setPose(action, handParam, [currentFrame], bones) return currentFrame -def tocar(action, input_hand, bones, pose, initialFrame = 18, degree = 30, frameJump = 10): +def tocar(action, mov_param, bones, initialFrame = 25, degree = 30, frameJump = 10): currentFrame = initialFrame - endFrame = initialFrame + 2 * frameJump - handParam = input_hand[-3:] + handParam = read_hand_param(mov_param) util.setPose(action, handParam, [initialFrame], bones) + pose = util.armature.pose.bones["ik_FK.R" if util.rightBonesConf == bones else "ik_FK.L"] lado = "BnMao.R" if util.rightBonesConf == bones else "BnMao.L" bnMao = bpy.context.object.pose.bones[lado] - bnMao.bone.select = True - currentFrame += frameJump - util.apply_rotation(bnMao, "X", currentFrame, endFrame, -degree) currentFrame += frameJump - util.apply_rotation(bnMao, "X", currentFrame, endFrame, degree) - util.setPose([action[0]], [handParam[0]], [currentFrame], bones) + util.apply_rotation(bnMao, "X", currentFrame, -degree) + pose = util.armature.pose.bones["ik_FK.R" if util.rightBonesConf == bones else "ik_FK.L"] currentFrame += frameJump - bnMao.bone.select = False + util.apply_rotation(bnMao, "X", currentFrame, degree) + util.setPose(action[0:2], handParam[0:2], [currentFrame], bones) return currentFrame -def cocar(action, input_hand, bones, initialFrame = 18, repetition = 2, frameJump = 6): +def cocar(action, mov_param, bones, initialFrame = 18, frameJump = 10): currentFrame = initialFrame - pa_index = input_hand[-1] + pa_index = mov_param['articulacao'] if 'articulacao' in mov_param else 0 + repetition = mov_param['repeticoes'] if 'repeticoes' in mov_param else 2 for i in range(0, repetition): - util.setPose(action, [util.cocar_mao_aberta_index, pa_index, util.cocar_orientation_index], [currentFrame], bones) + util.setPose(action, [util.cocar_mao_aberta_index, pa_index, util.cocar_orientation_index], [currentFrame], bones, False) currentFrame += frameJump - lastFrame = i == repetition - 1 - util.setPose(action, [util.cocar_mao_fechada_index, pa_index, util.cocar_orientation_index], [currentFrame], bones) + util.setPose(action, [util.cocar_mao_fechada_index, pa_index, util.cocar_orientation_index], [currentFrame], bones, False) currentFrame += frameJump return currentFrame -def alisar(action, input_hand, pose, bones, initialFrame = 18, frameJump = 10, width = 0.25): +def alisar(action, mov_param, bones, initialFrame = 18, frameJump = 10, width = 0.25): currentFrame = initialFrame - orientation, repetition = input_hand[2:4] - handParam = input_hand[-3:] - util.setPose(action, handParam, util.hands_default_frames, bones) - - if (orientation == "perpendicular"): - currentFrame = alisar_xy(pose, 1, repetition, initialFrame, frameJump, width) - elif (orientation == "paralelo"): - currentFrame = alisar_xy(pose, 0, repetition, initialFrame, frameJump, width) - elif (orientation == "diagonal-direita"): - currentFrame = alisar_diagonal(pose, True, repetition, initialFrame, frameJump, width) - elif (orientation == "diagonal-esquerda"): - currentFrame = alisar_diagonal(pose, False, repetition, initialFrame, frameJump, width) - + plane = mov_param['plano'] if 'plano' in mov_param else "perpendicular" + repetition = mov_param['repeticoes'] if 'repeticoes' in mov_param else 2 + handParam = read_hand_param(mov_param) + util.setPose(action, handParam, [currentFrame], bones) + boneIK = util.armature.pose.bones["ik_FK.R" if util.rightBonesConf == bones else "ik_FK.L"] + + if (plane == "perpendicular"): + currentFrame = alisar_xy(boneIK, 1, repetition, currentFrame, frameJump, width) + elif (plane == "paralelo"): + currentFrame = alisar_xy(boneIK, 0, repetition, currentFrame, frameJump, width) + elif (plane == "diagonal-direita"): + currentFrame = alisar_diagonal(boneIK, True, repetition, currentFrame, frameJump, width) + elif (plane == "diagonal-esquerda"): + currentFrame = alisar_diagonal(boneIK, False, repetition, currentFrame, frameJump, width) util.setPose(action, handParam, [currentFrame], bones) return currentFrame -def alisar_xy(pose, orientation_index, repetition, initialFrame = 18, frameJump = 10, width = 0.25): +def alisar_xy(boneIK, orientation_index, repetition, initialFrame = 18, frameJump = 10, width = 0.25): currentFrame = initialFrame - center = pose.location.x, pose.location.y, pose.location.z - + location = util.get_bone_data_from_frame(boneIK, currentFrame, 'location') + center = location.x, location.y, location.z for i in range(0, repetition): - pose.location[orientation_index] = center[orientation_index] - width - util.keyframe_insert(pose, 'location', currentFrame) + boneIK.location = center + boneIK.location[orientation_index] = center[orientation_index] - width + util.keyframe_insert(boneIK, 'location', currentFrame) currentFrame += frameJump - pose.location[orientation_index] = center[orientation_index] + width - util.keyframe_insert(pose, 'location', currentFrame) + boneIK.location = center + boneIK.location[orientation_index] = center[orientation_index] + width + util.keyframe_insert(boneIK, 'location', currentFrame) currentFrame += frameJump return currentFrame -def alisar_diagonal(pose, to_right, repetition, initialFrame = 18, frameJump = 10, width = 0.25): +def alisar_diagonal(boneIK, to_right, repetition, initialFrame = 18, frameJump = 10, width = 0.25): currentFrame = initialFrame - center = pose.location.x, pose.location.y, pose.location.z - + location = util.get_bone_data_from_frame(boneIK, currentFrame, 'location') + center = location.x, location.y, location.z for i in range(0, repetition): - pose.location[0] = center[0] - width if to_right else center[0] - width - pose.location[1] = center[1] - width if to_right else center[1] + width - - util.keyframe_insert(pose, 'location', currentFrame) + boneIK.location = center + boneIK.location[0] = center[0] - width if to_right else center[0] - width + boneIK.location[1] = center[1] - width if to_right else center[1] + width + util.keyframe_insert(boneIK, 'location', currentFrame) currentFrame += frameJump - - pose.location[0] = center[0] + width if to_right else center[0] + width - pose.location[1] = center[1] + width if to_right else center[1] - width - util.keyframe_insert(pose, 'location', currentFrame) + boneIK.location = center + boneIK.location[0] = center[0] + width if to_right else center[0] + width + boneIK.location[1] = center[1] + width if to_right else center[1] - width + util.keyframe_insert(boneIK, 'location', currentFrame) currentFrame += frameJump return currentFrame -""" -# descontinuada: circular_or_semiCircular -def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensity = 5, initialFrame = 18, turn = None): - center = pose.location.x, pose.location.y, pose.location.z - if(orientation == 'perpendicular'): - if(direction == 'horario'): - endFrame = circular(center, radius, 1, 0, 2, pose, 0, laps, intensity, initialFrame, turn) - else: - endFrame = locationCircular(center, radius, 0, 1, 2, pose, 0, laps, intensity, initialFrame, turn) - elif(orientation == 'paralelo'): - if(direction == 'horario'): - endFrame = locationCircular(center, radius, 1, 2, 0, pose, 0, laps, intensity, initialFrame, turn) - else: - endFrame = locationCircular(center, radius, 2, 1, 0, pose, 0, laps, intensity, initialFrame, turn) - elif(orientation == 'plano'): - if(direction == 'horario'): - endFrame = locationCircular(center, radius, 2, 0, 1, pose, 0, laps, intensity, initialFrame, turn) - else: - endFrame = locationCircular(center, radius, 0, 2, 1, pose, 0, laps, intensity, initialFrame, turn) - return endFrame -""" - # Obs.: A velocidade do movimento vai ser a relacao entre tamanho do raio e o periodo # quanto maior o periodo mais keyframes # quanto menor o raio mais rapido @@ -200,4 +179,4 @@ def circular(obj, frame_atual, raio, periodo, x = 0, y = 1, usar_lado_oposto = F util.keyframe_insert(obj, 'location', frame_atual) frame_atual += 1 util.keyframe_insert(obj, 'location', frame_atual) - return periodo - 1 + return periodo - 1 \ No newline at end of file diff --git a/util.py b/util.py index fed92f6..937ab5b 100644 --- a/util.py +++ b/util.py @@ -5,6 +5,7 @@ import math import pyutil import os import sys +import copy from bmesh_collision import bmesh_check_intersect_objects armature = bpy.context.scene.objects.get('Armature.001') @@ -20,27 +21,15 @@ dict_bones = { } # Vetor com indices de cada bone do lado direito -# rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66] +rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66] # Vetor com indices de cada bone do lado esquerdo -# leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82] - -# Vetor com indices de cada bone da face -# faceBonesConf = [15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47] - -# Vetor com indices de todos os bones -# allBones = list(range(len(armature.pose.bones))) - -# define a posição dos keyframes -# hands_default_frames = [15] - -# define a posição dos keyframes -# hands_frames_retilineo = [30, 33] +leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82] # Movimento coçar - Índices de poses -cocar_mao_aberta_index = 56 +cocar_mao_aberta_index = 55 cocar_mao_fechada_index = 24 -cocar_orientation_index = 20 +cocar_orientation_index = 11 # Action expressão facial facial_expression_id = '07_facial' @@ -83,6 +72,9 @@ def deselect_bones(bones = bpy.context.object.pose.bones): return def delete_all_keyframes(): + bpy.ops.object.mode_set(mode = 'OBJECT') + bpy.ops.object.select_all(action = "DESELECT") + bpy.ops.object.mode_set(mode = 'POSE') bpy.context.active_object.animation_data_clear() for obj in bpy.data.objects: obj.animation_data_clear() @@ -90,9 +82,6 @@ def delete_all_keyframes(): # Função responsável por selecionar as pose-libs e setar os frames def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True): - bpy.ops.object.mode_set(mode = 'OBJECT') - bpy.ops.object.select_all(action="DESELECT") - bpy.ops.object.mode_set(mode = 'POSE') for x in range(len(positionFrames)): for l in range(len(actions)): action = actions[l] @@ -108,6 +97,9 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True) keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO) def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): + # Limit hand depth + if ("ik_FK" in bone.name and bone.location.z < 1): + bone.location.z = 1 bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) keyframe_id = bone.name + "_" + path last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0 @@ -124,18 +116,22 @@ def resetIKPosition(isRightHand): def resetBnMaoPosition(isRightHand): armature.pose_library = bpy.data.actions[orient_direita_id if isRightHand else orient_esquerda_id] bpy.ops.poselib.apply_pose(pose_index = 0) - -def checkRotation(bone, positionFrame, last_keyframe): + +def get_bone_data_from_frame(bone, positionFrame, path): scene = bpy.context.scene frame_current = scene.frame_current scene.frame_set(positionFrame) - boneRQ = bone.rotation_quaternion.to_euler() + result = copy.copy(bone.location) if path == 'location' else copy.copy(bone.rotation_quaternion) scene.frame_set(frame_current) + return result + +def checkRotation(bone, positionFrame, last_keyframe): + boneRQ = get_bone_data_from_frame(bone, positionFrame, 'rotation_quaternion') isRightHand = ".R" in bone.name resetBnMaoPosition(isRightHand) valid_rotation = validate_rotation(bone, positionFrame, last_keyframe) if (not valid_rotation): - new_rotation = boneRQ.to_quaternion() * (-1) + new_rotation = boneRQ * (-1) bone.rotation_quaternion = new_rotation bone.keyframe_insert(data_path = 'rotation_quaternion', index = -1, frame = positionFrame) @@ -168,11 +164,14 @@ def check_collision(objName, otherObjName, initFrame, endFrame): frame_current = scene.frame_current startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2)) collisionFrame = -1 + for i in range(startFrame, endFrame + 1, 1): scene.frame_set(i) obj = scene.objects.get(objName) otherObj = scene.objects.get(otherObjName) if (bmesh_check_intersect_objects(obj, otherObj)): + pyutil.log("bla") + pyutil.log(i) collisionFrame = i break scene.frame_set(frame_current) @@ -215,27 +214,6 @@ def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.f bpy.ops.wm.quit_blender() return -""" -def get_endFrame(json_input, hands_frames_retilineo): - endsFrame = [18] - if(json_input["rightHand"] != []): - if(json_input["rightHand"][0] == "circular"): - # Sugestao: json_input["rightHand"][4] eh o número de voltas/repeticoes? colocar numa variavel - endsFrame.append(int(json_input["rightHand"][4]*8*5+18)) - elif(json_input["rightHand"][0] == "semicircular"): - endsFrame.append(int(json_input["rightHand"][4]*5*5+18)) - elif(json_input["rightHand"][0] == "retilineo"): - endsFrame.append(max(hands_frames_retilineo)) - if(json_input["leftHand"] != []): - if(json_input["leftHand"][0] == "circular"): - endsFrame.append(int(json_input["leftHand"][4]*8*5+18)) - elif(json_input["leftHand"][0] == "semicircular"): - endsFrame.append(int(json_input["rightHand"][4]*5*5+18)) - elif(json_input["rightHand"][0] == "retilineo"): - endsFrame.append(max(hands_frames_retilineo)) - return(max(endsFrame)) -""" - def validate_rotation(bone, endFrame, startFrame = 0): if (endFrame - startFrame == 1): return True @@ -250,12 +228,12 @@ def validate_rotation(bone, endFrame, startFrame = 0): scene.frame_set(frame_current) for k in range(1, len(rotFrames), 1): for i in range(0, 3, 1): - if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi/2: + if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi/3: return False return True # Axis: "X", "Y" e "Z" -def apply_rotation(bone, axis, currentFrame, endFrame, degree): +def apply_rotation(bone, axis, currentFrame, degree): new_rotation = bone.rotation_quaternion.to_euler() new_rotation.rotate_axis(axis, math.radians(degree)) new_rotation = new_rotation.to_quaternion() -- libgit2 0.21.2