From 6bf2e3c28ace3a8a604de379978fad4973a15e7f Mon Sep 17 00:00:00 2001 From: André Araújo Date: Tue, 25 Aug 2015 13:21:37 -0300 Subject: [PATCH] Adiciona movimento pontual --- Makefile | 38 +++++++++++++++++++++++++++++++++----- decode.py | 5 +---- facial.py | 25 +++++++++++-------------- moves.py | 46 +++++++++++++++++++++++++++++++++++++--------- util.py | 25 ++++++++++++++++++++++--- 5 files changed, 104 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 7121222..dfab752 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ -JSON = \ +#JSON = $(JSON_CIRCULAR) +JSON = $(JSON_PONTUAL) + +JSON_CIRCULAR = \ '{ \ "userId": "lavid", \ - "sinal": "Modelo JSON", \ + "sinal": "modelo_circular", \ "interpolacao": "normal", \ "movimentos": [ \ { \ @@ -17,9 +20,9 @@ JSON = \ "velocidade": "normal", \ "lado_oposto": false, \ "sentido_inverso": false, \ - "articulacao": 124, \ - "configuracao": 60, \ - "orientacao": 142 \ + "articulacao": 80, \ + "configuracao": 10, \ + "orientacao": 20 \ } \ }, \ "mao_direita": { \ @@ -39,6 +42,31 @@ JSON = \ ] \ }' +JSON_PONTUAL = \ +'{ \ + "userId": "lavid", \ + "sinal": "modelo_pontual", \ + "interpolacao": "normal", \ + "movimentos": [ \ + { \ + "facial": { \ + "expressao": 10, \ + "transicao": "normal", \ + "duracao": "normal" \ + }, \ + "mao_direita": { \ + "pontual": { \ + "articulacao": 71, \ + "configuracao": 19, \ + "orientacao": 11 \ + } \ + }, \ + "mao_esquerda": { \ + } \ + } \ + ] \ +}' + BLEND = avatar_cartoon_v2.74.blend CONTROLLER = controller.py MAIN = libras.py diff --git a/decode.py b/decode.py index dcb1ab6..395d6e9 100644 --- a/decode.py +++ b/decode.py @@ -9,9 +9,6 @@ def circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, # 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 @@ -49,7 +46,7 @@ def redemoinho(js_movement, current_frame, frame_jump, is_right_hand): pass def pontual(js_movement, current_frame, frame_jump, is_right_hand): - pass + return moves.pontual(js_movement, current_frame, frame_jump, is_right_hand) def senoidal(js_movement, current_frame, frame_jump, is_right_hand): pass diff --git a/facial.py b/facial.py index 6ef2916..1962673 100644 --- a/facial.py +++ b/facial.py @@ -5,11 +5,11 @@ import util # duracao na posicao selecionada dict_duration = { - 'inicial': 20, + 'inicial': 10, 'lento': 15, 'normal': 10, 'rapido': 5, - 'final': 20, + 'final': 10, } # tempo de entrada e saida na posicao selecionada @@ -86,28 +86,25 @@ def decode_expression(timeline_facial, js_facial, initial_interpolation = dict_d frame_transition = dict_transition[js_facial['transicao']] # insere o primeiro keyframe if (timeline_facial == 0): - set_expression(timeline_facial, 0, initial_interpolation) - set_expression(timeline_facial, index, frame_duration, frame_transition) - set_expression(timeline_facial, 0, frame_duration) + timeline_facial = set_expression(timeline_facial, 0, initial_interpolation) + timeline_facial = set_expression(timeline_facial, index, frame_duration, frame_transition) + timeline_facial = set_expression(timeline_facial, 0, frame_duration) return timeline_facial """ # unit test def main(): - interpolation_start = 20 - interpolation_end = 20 timeline_facial = 0 - pose_max_range = round(bpy.data.actions[library_name].frame_range[1]) util.delete_all_keyframes() - apply_pose(0, util.facial_expression_id) - for i in range(0, pose_max_range + 1): + expressoes = list(range(0, round(bpy.data.actions[util.facial_expression_id].frame_range[1]) + 1)) + expressoes = [10, 11] + for i in expressoes: js_facial = { - "expressao": i, # random.randint(0, pose_max_range), - "transicao": 'normal', - "duracao": 'normal' + "expressao": i, + "transicao": "normal", + "duracao": "normal" } timeline_facial = decode_expression(timeline_facial, js_facial, dict_duration['inicial']) - print('facial expression %d current frame:' % (js_facial['expressao']), timeline_facial) bpy.context.scene.frame_end = timeline_facial + dict_duration['final'] bpy.ops.screen.animation_play(reverse = False) diff --git a/moves.py b/moves.py index 5f354c5..f5fa8a8 100644 --- a/moves.py +++ b/moves.py @@ -37,9 +37,9 @@ def riscar(action, mov_param, bones, initialFrame = 25, frameJump = 10, bnAntBra bnMao = bpy.context.object.pose.bones["BnMao." + lado] currentFrame += frameJump util.apply_rotation(bnMao, "Y", currentFrame, bnMaoDegree) - currentFrame += int(frameJump/2) + currentFrame += int(frameJump/2) util.apply_rotation(bnMao, "Y", currentFrame, (-1)*bnMaoDegree) - currentFrame += int(frameJump/2) + currentFrame += int(frameJump/2) util.apply_rotation(bnMao, "Y", currentFrame, (-2)*bnMaoDegree) currentFrame += frameJump util.setPose(action, handParam, [currentFrame], bones) @@ -138,14 +138,14 @@ def alisar_diagonal(boneIK, to_right, repetition, initialFrame = 18, frameJump = # raio: "grande" raio = 1.5, velocidade: "normal" periodo = 55 # raio: "grande" raio = 1.5, velocidade: "lento" periodo = 65 # @param obj: (objeto) bone, mesh, e.g. -# @param frame_atual: (int) posicao onde o primeiro keyframe vai ser inserido +# @param current_frame: (int) posicao onde o primeiro keyframe vai ser inserido # @param raio: (int) raio da circunferencia # @param periodo: (int) quantidade de keyframes necessarios para completar uma volta completa # @param x: (int) in [0,1,2] define qual eixo vai variar no seno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) # @param y: (int) in [0,1,2] define qual eixo vai variar no cosseno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) # @param usar_lado_oposto: (bool) inverte o lado da primeira posicao (pode ser util em alguns casos para espelhar) # @param usar_sentido_oposto (bool) inverte o sentido do movimento (horario para anti-horario) -def circular(obj, frame_atual, raio, periodo, x = 0, y = 1, usar_lado_oposto = False, usar_sentido_oposto = False, meia_volta = False): +def circular(obj, current_frame, raio, periodo, x = 0, y = 1, usar_lado_oposto = False, usar_sentido_oposto = False, meia_volta = False): # limita inferiormente if (periodo < 16): periodo = 16 @@ -173,10 +173,38 @@ def circular(obj, frame_atual, raio, periodo, x = 0, y = 1, usar_lado_oposto = F limite = round(limite / 2) for i in range(k, limite + 1): # reduz a quantidade de keyframes - if (frame_atual % 2 == 0): + if (current_frame % 2 == 0): obj.location[x] = loc[x] + (raio * math.cos(i / periodo * (2 * math.pi))) obj.location[y] = loc[y] + (raio * math.sin(i / periodo * (2 * math.pi))) - util.keyframe_insert(obj, 'location', frame_atual) - frame_atual += 1 - util.keyframe_insert(obj, 'location', frame_atual) - return periodo - 1 \ No newline at end of file + util.keyframe_insert(obj, 'location', current_frame) + current_frame += 1 + util.keyframe_insert(obj, 'location', current_frame) + return periodo - 1 + +def pontual(js_movement, current_frame, frame_jump, is_right_hand): + #import facial + print(util.right_bones_conf) + hand_param = read_hand_param(js_movement) + bones = util.right_bones_conf if is_right_hand else util.leftBonesConf + #poselib = None + if (is_right_hand): + #poselib = util.pa_direita_id + hand_actions = util.right_hand_actions + else: + #poselib = util.pa_esquerda_id + hand_actions = util.left_hand_actions + #ik_bones = util.dict_bones[poselib] + #util.select_bones(ik_bones) + util.keyframe_insert(bones, 'location', current_frame, False) + #facial.keyframe_insert(current_frame, ik_bones, ['location']) + current_frame += frame_jump + #facial.apply_pose(js_movement['articulacao'], poselib) + pyutil.log("XXXXXXXXXXXXXXXX") + util.setPose(hand_actions, hand_param, [current_frame], bones, False) + pyutil.log("YYYYYYYYYYYYYYYY") + #facial.keyframe_insert(current_frame, ik_bones, ['location']) + current_frame += frame_jump + #facial.keyframe_insert(current_frame, ik_bones, ['location']) + util.keyframe_insert(bones, 'location', current_frame, False) + #util.deselect_bones(ik_bones) + return current_frame diff --git a/util.py b/util.py index 1a36f5c..5e31d07 100644 --- a/util.py +++ b/util.py @@ -14,12 +14,14 @@ dict_bones = { "01_conf_direita": ['BnDedo.1.R', 'BnDedo.1.R.006', 'BnDedo.1.R.005', 'BnDedo.1.R.001', 'BnDedo.1.R.008', 'BnDedo.1.R.007', 'BnDedo.1.R.002', 'BnDedo.1.R.010', 'BnDedo.1.R.009', 'BnDedo.1.R.003', 'BnDedo.1.R.012', 'BnDedo.1.R.011', 'BnDedo.1.R.004', 'BnDedo.1.R.014', 'BnDedo.1.R.013'], "02_conf_esquerda": ['BnDedo.1.L', 'BnDedo.1.L.006', 'BnDedo.1.L.005', 'BnDedo.1.L.001', 'BnDedo.1.L.008', 'BnDedo.1.L.007', 'BnDedo.1.L.002', 'BnDedo.1.L.010', 'BnDedo.1.L.009', 'BnDedo.1.L.003', 'BnDedo.1.L.012', 'BnDedo.1.L.011', 'BnDedo.1.L.004', 'BnDedo.1.L.014', 'BnDedo.1.L.013'], "03_pa_direita": ['ik_FK.R', 'BnPolyV.R'], - "04_pa_direita": ['ik_FK.R', 'BnPolyV.R'], + "04_pa_esquerda": ['ik_FK.L', 'BnPolyV.L'], "05_orient_direita": ['BnMao.R'], "06_orient_esquerda": ['BnMao.L'], "07_facial": ['BnPescoco', 'BnCabeca', 'BnSobrancCentro.L', 'BnSobrancCentro.R', 'BnSobrancLateral.L', 'BnSobrancLateral.R', 'BnPalpebSuper.L', 'BnPalpebInfe.L', 'BnSobrancCentro', 'BnLabioCentroSuper', 'BnBochecha.L', 'BnBochecha.R', 'BnLabioCentroInfer', 'BnBocaCanto.L', 'BnBocaCanto.R', 'BnMandibula', 'BnLingua', 'BnLingua.003', 'BnLingua.001', 'BnLingua.002', 'BnPalpebSuper.R', 'BnPalpebInfe.R', 'BnOlhosMira', 'BnOlhoMira.L', 'BnOlhoMira.R', 'BnOlho.L', 'BnOlho.R'] } +right_bones_conf = dict_bones["01_conf_direita"] + dict_bones["03_pa_direita"] + dict_bones["05_orient_direita"] + # 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] @@ -87,22 +89,29 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True) for x in range(len(positionFrames)): for l in range(len(actions)): action = actions[l] + select_bones(bones) armature.pose_library = bpy.data.actions[action] bpy.ops.poselib.apply_pose(pose_index = parametesConf[l]) + deselect_bones(bones) + bpy.context.object.pose_library = None for i in range(0, (len(bones))): bone = armature.pose.bones[bones[i]] validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name - validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name + validPA = action in [pa_direita_id, pa_esquerda_id] and ("ik_FK" in bone.name or "BnPolyV" in bone.name) validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name if (validHandConf or validPA or validO): keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO) keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO) -def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): +def internal_keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): # Limit hand depth + if ("ik_FK.R" == bone.name): + print("VERDADE", bone.location, positionFrame) if ("ik_FK" in bone.name and bone.location.z < 1): bone.location.z = 1 + bone.bone.select = True bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) + bone.bone.select = False keyframe_id = bone.name + "_" + path last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0 last_keyframe_dict[keyframe_id] = positionFrame @@ -111,6 +120,16 @@ def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFla if (collisionFlag): checkCollision(bone, path, positionFrame, last_keyframe) +def keyframe_insert(bones, path, positionFrame, collisionFlag = True, rotationFlag = False): + if (isinstance(bones, list)): + for bone in bones: + if (isinstance(bone, int) or isinstance(bone, str)): + internal_keyframe_insert(bpy.context.object.pose.bones[bone], path, positionFrame, collisionFlag, rotationFlag) + else: + internal_keyframe_insert(bone, path, positionFrame, collisionFlag, rotationFlag) + else: + internal_keyframe_insert(bones, path, positionFrame, collisionFlag, rotationFlag) + def resetIKPosition(isRightHand): armature.pose_library = bpy.data.actions[pa_direita_id if isRightHand else pa_esquerda_id] bpy.ops.poselib.apply_pose(pose_index = 0) -- libgit2 0.21.2