def test_stance_shoulder_01(self): arm_slope = MVector3D(-1.837494969367981, 18.923479080200195, 0.4923856854438782) shoulder_slope = MVector3D(-0.8141360282897949, 19.6701602935791, 0.4931679964065552) neck_base = MVector3D(0.0, 18.923479080200195, 0.4923856854438782) # 傾きパターン test_slope_param = [arm_slope, shoulder_slope, neck_base] slope_test_params = list(itertools.product(test_slope_param, repeat=2)) # random.shuffle(slope_test_params) # 数値パターン test_number_param = [0, -1, 1] number_test_params = list( itertools.product(test_number_param, repeat=3)) # random.shuffle(number_test_params) target_test_params = list( itertools.product(slope_test_params, number_test_params)) for param in target_test_params: print("------------------") print("param[0][0]: %s" % param[0][0]) print("param[0][1]: %s" % param[0][1]) print("param[1][0]: %s" % param[1][0]) print("param[1][1]: %s" % param[1][1]) print("param[1][2]: %s" % param[1][2]) rep_shoulder_slope = (param[0][0] - param[0][1]).normalized() rep_shoulder_slope_up = MVector3D(param[1][0], param[1][1], param[1][2]) rep_shoulder_slope_cross = MVector3D.crossProduct( rep_shoulder_slope, rep_shoulder_slope_up).normalized() rep_shoulder_initial_slope_qq = MQuaternion.fromDirection( rep_shoulder_slope, rep_shoulder_slope_cross) print("rep_shoulder_slope: %s" % rep_shoulder_slope) print("rep_shoulder_slope_up: %s" % rep_shoulder_slope_up) print("qq: %s" % rep_shoulder_initial_slope_qq.toEulerAngles()) self.assertTrue(True)
def calc_global_pos(model: PmxModel, links: BoneLinks, motion: VmdMotion, fno: int, limit_links=None, return_matrix=False, is_local_x=False): trans_vs = calc_relative_position(model, links, motion, fno, limit_links) add_qs = calc_relative_rotation(model, links, motion, fno, limit_links) # 行列 matrixs = [MMatrix4x4() for i in range(links.size())] for n, (lname, v, q) in enumerate(zip(links.all().keys(), trans_vs, add_qs)): # 行列を生成 matrixs[n] = MMatrix4x4() # 初期化 matrixs[n].setToIdentity() # 移動 matrixs[n].translate(v) # 回転 matrixs[n].rotate(q) total_mats = {} global_3ds_dic = OrderedDict() for n, (lname, v) in enumerate(zip(links.all().keys(), trans_vs)): if n == 0: total_mats[lname] = MMatrix4x4() total_mats[lname].setToIdentity() for m in range(n): # 最後のひとつ手前までループ if m == 0: # 0番目の位置を初期値とする total_mats[lname] = matrixs[0].copy() else: # 自分より前の行列結果を掛け算する total_mats[lname] *= matrixs[m].copy() # 自分は、位置だけ掛ける global_3ds_dic[lname] = total_mats[lname] * v # 最後の行列をかけ算する total_mats[lname] *= matrixs[n].copy() # ローカル軸の向きを調整する if n > 0 and is_local_x: # ボーン自身にローカル軸が設定されているか local_x_matrix = MMatrix4x4() local_x_matrix.setToIdentity() local_axis_qq = MQuaternion() if model.bones[lname].local_x_vector == MVector3D(): # ローカル軸が設定されていない場合、計算 # 自身から親を引いた軸の向き local_axis = model.bones[lname].position - links.get( lname, offset=-1).position local_axis_qq = MQuaternion.fromDirection( local_axis.normalized(), MVector3D(0, 0, 1)) else: # ローカル軸が設定されている場合、その値を採用 local_axis_qq = MQuaternion.fromDirection( model.bones[lname].local_x_vector.normalized(), MVector3D(0, 0, 1)) local_x_matrix.rotate(local_axis_qq) total_mats[lname] *= local_x_matrix if return_matrix: # 行列も返す場合 return global_3ds_dic, total_mats return global_3ds_dic
def not_test_stance_shoulder_08(self): new_rep_to_pos = MVector3D(16.638640587237894, 19.455697325211673, 4.067013732312591) # rep_base_pos = MVector3D(15.541596036361701, 18.419343683301417, 2.4565491530944494) rep_from_pos = MVector3D(16.07129122417615, 19.252113744303983, 2.952803072461259) up_pos = MVector3D(0.02597404821369409, -0.6341368197928823, 0.7727844735774392) parent_qq = MQuaternion.fromEulerAngles(4.444080622855673, 131.6889133202979, -6.602768822699441) arm_pos = MVector3D(-1.837494969367981, 18.923479080200195, 0.4923856854438782) shoulder_pos = MVector3D(-0.8141360282897949, 19.6701602935791, 0.4931679964065552) neck_base_pos = MVector3D(0.0, 18.923479080200195, 0.4923856854438782) another_arm_pos = MVector3D(1.837494969367981, 18.923479080200195, 0.4923856854438782) another_shoulder_pos = MVector3D(0.8141360282897949, 19.6701602935791, 0.493167906999588) # 傾きパターン test_slope_param = [arm_pos, shoulder_pos, neck_base_pos] all_slope_test_params = list( itertools.product(test_slope_param, repeat=2)) slope_test_params = [(x00, x01) for (x00, x01) in all_slope_test_params if x00 != x01] # upパターン test_up_param = [ arm_pos, shoulder_pos, neck_base_pos, another_arm_pos, another_shoulder_pos ] all_up_test_params = list(itertools.product(test_up_param, repeat=2)) up_test_params = [(x00, x01) for (x00, x01) in all_up_test_params if x00 != x01] # 数値パターン test_number_param = [0, -1, 1] all_number_test_params = list( itertools.product(test_number_param, repeat=3)) number_test_params = [(x00, x01, x02) for (x00, x01, x02) in all_number_test_params if x00 == 0 or x01 == 0 or x02 == 0] target_test_params = list( itertools.product(slope_test_params, number_test_params, up_test_params)) print(len(target_test_params)) random.shuffle(target_test_params) for params in target_test_params: print("-----------------------") print(params[0][0]) print(params[0][1]) print(params[1]) print(params[2][0]) print(params[2][1]) rep_shoulder_slope = (params[0][0] - params[0][1]).normalized() print("rep_shoulder_slope: %s" % rep_shoulder_slope) rep_shoulder_slope_up = MVector3D(params[1][0], params[1][1], params[1][2]) print("rep_shoulder_slope_up: %s" % rep_shoulder_slope_up) shoulder_cross = MVector3D.crossProduct( rep_shoulder_slope, rep_shoulder_slope_up).normalized() print("shoulder_cross: %s" % shoulder_cross) initial = MQuaternion.fromDirection(rep_shoulder_slope, shoulder_cross) print("initial: %s" % initial.toEulerAngles()) direction = new_rep_to_pos - rep_from_pos up = MVector3D.crossProduct(direction, up_pos) from_orientation = MQuaternion.fromDirection( direction.normalized(), up.normalized()) from_rotation = parent_qq.inverted( ) * from_orientation * initial.inverted() from_rotation.normalize() print("rot %s" % from_rotation.toEulerAngles4MMD()) print("original: %s" % MVector3D( 21.338723875696445, 15.845333083479046, 37.954108757721826))
def not_test_stance_shoulder_06(self): new_rep_to_pos = MVector3D(16.638640587237887, 19.455697325211673, 4.067013732312591) rep_base_pos = MVector3D(15.527995423468052, 19.158781645638516, 2.353690174209908) up_pos = MVector3D(0.02597404821369409, -0.6341368197928823, 0.7727844735774392) parent_qq = MQuaternion.fromEulerAngles(4.444080622855673, 131.6889133202979, -6.602768822699441) arm_pos = MVector3D(-1.837494969367981, 18.923479080200195, 0.4923856854438782) shoulder_pos = MVector3D(-0.8141360282897949, 19.6701602935791, 0.4931679964065552) neck_base_pos = MVector3D(0.0, 19.6701602935791, 0.4931679517030716) # stance_shoulder2neck_qq = MQuaternion.fromEulerAngles(0.015789129707102025, -0.040575112727633096, 42.52534119964952) # stance_shoulder2arm_qq = MQuaternion.fromEulerAngles(0.011536139571057251, 0.03538278693844499, -36.1158910081693) # 傾きパターン test_slope_param = [arm_pos, shoulder_pos, neck_base_pos] all_slope_test_params = list( itertools.product(test_slope_param, repeat=2)) slope_test_params = [(x00, x01) for (x00, x01) in all_slope_test_params if x00 != x01] # 数値パターン test_number_param = [0, -1, 1] all_number_test_params = list( itertools.product(test_number_param, repeat=3)) number_test_params = [(x00, x01, x02) for (x00, x01, x02) in all_number_test_params if x00 == 0 or x01 == 0 or x02 == 0] # qqパターン # test_qq_param = [stance_shoulder2neck_qq, stance_shoulder2neck_qq.inverted(), stance_shoulder2arm_qq, stance_shoulder2arm_qq.inverted(), MQuaternion()] test_qq_param = [MQuaternion()] target_test_params = list( itertools.product(slope_test_params, number_test_params, test_qq_param)) print(len(target_test_params)) random.shuffle(target_test_params) for params in target_test_params: print("-----------------------") print(params[0][0]) print(params[0][1]) print(params[1]) print(params[2].toEulerAngles()) rep_shoulder_slope = (params[0][0] - params[0][1]).normalized() print("rep_shoulder_slope: %s" % rep_shoulder_slope) rep_shoulder_slope_up = MVector3D(params[1][0], params[1][1], params[1][2]) print("rep_shoulder_slope_up: %s" % rep_shoulder_slope_up) initial = MQuaternion.fromDirection(rep_shoulder_slope, rep_shoulder_slope_up) print("initial: %s" % initial.toEulerAngles()) direction = new_rep_to_pos - rep_base_pos up = MVector3D.crossProduct(direction, up_pos) from_orientation = MQuaternion.fromDirection( direction.normalized(), up.normalized()) from_rotation = parent_qq.inverted( ) * from_orientation * initial.inverted() * params[2] from_rotation.normalize() print("rot %s" % from_rotation.toEulerAngles4MMD())