Skip to content

Commit

Permalink
ver5.01.03配布準備
Browse files Browse the repository at this point in the history
  • Loading branch information
miu200521358 committed Jun 30, 2021
1 parent 6ff7290 commit 151c79e
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
*.bat text eol=crlf
*.csv text eol=crlf
*.txt text eol=crlf
*.spec text encoding=shift-jis eol=crlf
*.spec text eol=crlf
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"version": "0.2.0",
"configurations": [

{
"name": "exec_sizing",
"type": "python",
Expand Down Expand Up @@ -234,6 +235,20 @@
"console": "integratedTerminal",
"python": "${command:python.interpreterPath}",
"stopOnEntry": false,
"args": [
"--verbose", "1",
"--out_log", "1",
]
},
{
"name": "exec_vrm2pmx",
"type": "python",
"request": "launch",
"program": "src/executor.py",
"cwd": "${workspaceFolder}/../vrm2pmx/",
"console": "integratedTerminal",
"python": "${command:python.interpreterPath}",
"stopOnEntry": false,
"args": [
"--verbose", "10",
"--out_log", "1",
Expand Down
18 changes: 15 additions & 3 deletions archive/Readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

�@�uVMD�T�C�W���O�@���[�J���Łv

�@�@ver5.01.02
�@�@ver5.01.03

�@�@�@�@�@�@�@�@�@�@�@�@�@�@�@�@�@miu200521358

Expand Down Expand Up @@ -44,7 +44,7 @@ https://seiga.nicovideo.jp/seiga/im9755721
���@�����t�@�C��
----------------------------------------------------------------

�@�EVMDSizing_5.01.02_64bit.exe�@�@�@�c�@�c�[���{�́iver5.00���64bit�ł݂̂ł��j
�@�EVMDSizing_5.01.03_64bit.exe�@�@�@�c�@�c�[���{�́iver5.00���64bit�ł݂̂ł��j
�@�EReadme.txt�@�@�@�@�@�@�@�@�@�@�c�@���h�~
�@�EVMD�T�C�W���OWiki�@�@�@�@�@�@ �c�@Wiki�ւ̃����N
�@�E�R���e���c�c���[�p�É�@�@�@�@�c�@�R���e���c�c���[�p�É�ւ̃����N
Expand Down Expand Up @@ -133,7 +133,7 @@ https://seiga.nicovideo.jp/seiga/im9755721
�@�@�@���W���܂ł̃{�[���ō\�����ꂽ�l�‘����f���Ȃǂ͒������܂��B

�E�‚ܐ�h�j�␳
�@�c�@�‚ܐ�h�j�̈ړ��ʂ��A���h�j�̉�]�ʂɕϊ����܂��B
�@�c�@�‚ܐ�h�j�̈ړ��ʂ��A���h�j�̉�]�ʂɕϊ����܂��B�i�‚ܐ�h�j�̒l�͏����l�ɂȂ�܂��j
�@�@�@�‚ܐ�h�j���g�������[�V�����Ō��ʂ�������₷���ł��B

�E���h�j�␳
Expand All @@ -148,6 +148,7 @@ https://seiga.nicovideo.jp/seiga/im9755721
�E���␳
�@�c�@�����X�^���X�̌��̌X���̈Ⴂ���l�����āA�����f���Ɠ������炢�ɓ������悤�A���ƌ�P�i����΁j�𒲐����܂��B
�@�@�@�����傫���������[�V�������_�C�i�~�b�N�ɂȂ�܂��B
�@�@�@����P�̒l�͌��ɕϊ����ĈڐA���܂��B�i��P�̒l�͏����l�ɂȂ�܂��j

�E�Z���^�[Y�␳
�@�c�@������̘r�̋������A�����f���Ɠ����悤�Ȉʒu�ɍ��킹��悤�A�Z���^�[�𒲐����܂��B
Expand Down Expand Up @@ -399,6 +400,17 @@ https://github.com/miu200521358/vmd_sizing
���@����
----------------------------------------------------------------

ver5.01.03�@�i2021/07/01�j
�@�@�E�@�\�lj��F�ϊ��O�Ȃǂ̕s���{�[���`�F�b�N���ɁA�{�[���̐������̃`�F�b�N�����킹�čs���悤�����lj�
�@�@�@�@�@�@�@�@���@D�{�[���Ȃǂ������Ă��邪����������Ă���ꍇ�Ȃǂɕ�����₷���Ȃ�܂��B
�@�@�E�@�\�ύX: �ʒu���킹
�@�@�@�@�@�@�@�@�E�Ђ��̊p�x��30�x�����ł���ꍇ�A�ʒu���킹�rIK��������Ђ������O����悤�����lj�
�@�@�@�@�@�@�@�@�@���@����ɔ����Ђ����t�����ɍ��܂���”\�����������͂�
�@�@�E�@�\�ύX�F�r�X�^���X�␳
�@�@�@�@�@�@�@�@�EISAO���~�N�Ŏ�񂪐܂��̂�����ł���悤��������
�@�@�@�@�@�@�@�@�@�iISAO���~�N�̏ꍇ�A���ƒ��w�����f����Ă�̂ŁA�\������x�[�X�ɒ�������j


ver5.01.02�@�i2021/05/04�j
�@�@�E�d�l�ύX�F�X�^���X�lj��␳�́u���h�j�␳�v���m�[�}���̌^���Ƒ��������Ă��܂��̂Ńf�t�H���gOFF�ɕύX
�@�@�EBugfix: IK�v�Z�����̃N�H�[�^�j�I���̂����Z���Ԃ��Ԉ���Ă����̂ŏC���i�ʒu���킹�E�ڐG����̐��x����j
Expand Down
2 changes: 2 additions & 0 deletions src/module/MMath.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ cdef class MQuaternion:

cpdef double toDegree(self)

cpdef double toDegreeSign(self, MVector3D local_axis)

cpdef double calcTheata(self, MQuaternion v)

cpdef data(self)
Expand Down
10 changes: 10 additions & 0 deletions src/module/MMath.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,16 @@ cdef class MQuaternion:
cpdef double toDegree(self):
return degrees(2 * acos(min(1, max(-1, self.scalar()))))

# 軸による符号付き角度に変換
cpdef double toDegreeSign(self, MVector3D local_axis):
cdef double deg = self.toDegree() * np.sign(MVector3D.dotProduct(self.vector(), local_axis)) * np.sign(self.scalar())

if abs(deg) > 180:
# 180度を超してる場合、フリップなので、除去
return (abs(deg) - 180) * np.sign(deg)

return deg

# 自分ともうひとつの値vとのtheta(変位量)を返す
cpdef double calcTheata(self, MQuaternion v):
return (1 - MQuaternion.dotProduct(self.normalized(), v.normalized()))
Expand Down
13 changes: 13 additions & 0 deletions src/module/MParams.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ cdef class BoneLinks:
def append(self, bone):
self.__links[bone.name] = bone.copy()

# リンクに挿入
def insert(self, bone, prev_bone_name):
new_links = {}
for lidx, lkey in enumerate(self.__links.keys()):
new_links[lkey] = self.__links[lkey].copy()

if lkey == prev_bone_name:
# 直前ボーンが見つかったら、その後に挿入する
new_links[bone.name] = bone.copy()

# 終わったら置き換える
self.__links = new_links

# リンクの反転
def reversed(self):
return reversed(self.__links)
Expand Down
193 changes: 193 additions & 0 deletions test/test_mmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,199 @@
logger = MLogger(__name__, level=1)



class LegIkTest(unittest.TestCase):

def test_leg_fk(self):
MLogger.initialize(level=MLogger.DEBUG, is_file=True)
logger = MLogger(__name__, level=MLogger.DEBUG)

pmx_path = "D:\\MMD\\MikuMikuDance_v926x64\\UserFile\\Model\\初音ミクVer2 準標準.pmx"
reader = PmxReader(pmx_path, is_check=False)
model = reader.read_data()

# for test_fno in ["0000", "0010", "0063", "0101", "0145", "0747"]:
for test_fno in ["0747"]:
# reader = VmdReader(f"D:\\MMD\\MikuMikuDance_v926x64\\UserFile\\Motion\\ダンス_1人\\バレリーコ 553\\ミク用バレリーコ_4870-_さとく式鶯丸ver0.90_S_20210605_084703_{test_fno}.vmd")
reader = VmdReader("D:\\MMD\\MikuMikuDance_v926x64\\UserFile\\Motion\\ダンス_1人\\バレリーコ 553\\ミク用バレリーコ_4870-_さとく式鶯丸ver0.90_S_20210605_084703.vmd")
motion = reader.read_data()

for direction in ["右", "左"]:
leg_fk_bone_name = f'{direction}足'
leg_twist_fk_bone_name = f'{direction}足捩り実体'
leg_ik_bone_name = "{0}足IK".format(direction)
knee_bone_name = "{0}ひざ".format(direction)
ankle_bone_name = "{0}足首".format(direction)
leg_fk_links = model.create_link_2_top_one(ankle_bone_name, is_defined=False)
leg_ik_links = model.create_link_2_top_one(leg_ik_bone_name, is_defined=False)

# デフォルト姿勢での足ボーンから見た足IKのローカル座標
_, leg_initial_fk_matrixs = MServiceUtils.calc_global_pos(model, leg_fk_links, VmdMotion(), 9, return_matrix=True)
leg_initial_ik_local_pos = leg_initial_fk_matrixs[leg_fk_bone_name].inverted() * model.bones[leg_ik_bone_name].position
leg_length = leg_initial_ik_local_pos.length()

# 足IKの高さ
leg_ik_height = model.bones[leg_ik_bone_name].position.y()
logger.warning(f"{direction}足: leg_length: {round(leg_length, 4)}, leg_ik_height: {round(leg_ik_height, 4)}")

# # IK計算用FKボーン(事前Y用) ----------
# leg_y_fk2ik_links = BoneLinks()

# # 足首
# leg_y_fk2ik_links.append(leg_fk_links.to_links(leg_fk_bone_name).get(ankle_bone_name))

# # ひざ
# knee_y_fk_bone = leg_fk_links.to_links(leg_fk_bone_name).get(knee_bone_name).copy()
# knee_y_fk_bone.ik_limit_min = MVector3D(0, -180, 0)
# knee_y_fk_bone.ik_limit_max = MVector3D(0, 10, 0)
# leg_y_fk2ik_links.append(knee_y_fk_bone)

# # 足
# leg_y_fk_bone = leg_fk_links.to_links(leg_fk_bone_name).get(leg_fk_bone_name).copy()
# leg_y_fk_bone.ik_limit_min = MVector3D(0, -30, 0)
# leg_y_fk_bone.ik_limit_max = MVector3D(0, 180, 0)
# leg_y_fk2ik_links.append(leg_y_fk_bone)

leg_fk_local_z_axis = MVector3D(0, 0, -1)
leg_fk_local_x_axis = model.get_local_x_axis(leg_fk_bone_name)
leg_fk_local_y_axis = MVector3D.crossProduct(leg_fk_local_x_axis, leg_fk_local_z_axis)
logger.warning(f"{direction}足: x_axis: {leg_fk_local_x_axis.to_log()}, y_axis: {leg_fk_local_y_axis.to_log()}")

# IK計算用FKボーン(足全体用) ----------
leg_fk2ik_links = BoneLinks()

# 足首
leg_fk2ik_links.append(leg_fk_links.to_links(leg_fk_bone_name).get(ankle_bone_name))

# ひざ
knee_fk_bone = leg_fk_links.to_links(leg_fk_bone_name).get(knee_bone_name).copy()
knee_fk_bone.ik_limit_min = MVector3D(0, -180, 0)
knee_fk_bone.ik_limit_max = MVector3D(0, 10, 0)
leg_fk2ik_links.append(knee_fk_bone)

# 足捩り
leg_twist_bone_pos = model.bones[leg_fk_bone_name].position + ((model.bones[knee_bone_name].position - model.bones[leg_fk_bone_name].position) / 2)
leg_twist_fk_bone = Bone(leg_twist_fk_bone_name, "", leg_twist_bone_pos, -1, 0, 0)
leg_twist_fk_bone.fixed_axis = leg_fk_local_x_axis
leg_fk2ik_links.append(leg_twist_fk_bone)

# FKリンクにも挿入する
leg_fk_links.insert(leg_twist_fk_bone, leg_fk_bone_name)

# 足
leg_fk_bone = leg_fk_links.to_links(leg_fk_bone_name).get(leg_fk_bone_name).copy()
# leg_fk_bone.ik_limit_min = MVector3D(-180, -30, -180)
# leg_fk_bone.ik_limit_max = MVector3D(180, 180, 180)
leg_fk2ik_links.append(leg_fk_bone)

# knee_local_z_axis = MVector3D(0, 0, -1)
# knee_local_x_axis = model.get_local_x_axis(knee_bone_name)
# knee_local_y_axis = MVector3D.crossProduct(knee_local_x_axis, knee_local_z_axis)

# leg_fk_local_x_axis = model.get_local_x_axis(leg_fk_bone_name)

for fno in motion.get_differ_fnos(0, [leg_fk_bone_name, leg_ik_bone_name], limit_degrees=30, limit_length=1):
leg_ik_bf = motion.calc_bf(leg_ik_bone_name, fno)
leg_fk_bf = motion.calc_bf(leg_fk_bone_name, fno).copy()
knee_bf = motion.calc_bf(knee_bone_name, fno).copy()
leg_fk_initial_global_3ds, leg_fk_initial_matrixs = MServiceUtils.calc_global_pos(model, leg_fk_links, motion, fno, \
limit_links=leg_fk_links.from_links(leg_fk_links.get(leg_fk_bone_name, offset=-1).name), return_matrix=True)
leg_fk_global_3ds, leg_fk_matrixs = MServiceUtils.calc_global_pos(model, leg_fk_links, motion, fno, return_matrix=True)

leg_ik_global_3ds = MServiceUtils.calc_global_pos(model, leg_ik_links, motion, fno)
leg_ik_global_pos = leg_ik_global_3ds[leg_ik_bone_name]

# # 初期足FKから見た、初期ひざのローカル座標
# knee_from_leg_local_pos = leg_fk_initial_matrixs["下半身"].inverted() * leg_fk_initial_global_3ds[leg_fk_bone_name]
# 足FKから見た、足IKのローカル座標
leg_ik_from_leg_local_pos = leg_fk_matrixs[leg_fk_bone_name].inverted() * leg_ik_global_pos
# 足首FKから見た、足IKのローカル座標
leg_ik_from_ankle_local_pos = leg_fk_matrixs[ankle_bone_name].inverted() * leg_ik_global_pos

# 足首FKから見て、足IKが乖離している場合、補正対象とする
# Yはマイナス(ローカルから見てプラス)の場合は接地して問題ない事が多いので、対象外とする。代わりに足IKのグローバルYが浮いてたら対象
# 足FKにかなり近い場合、対象外としておく(しゃがみとか)
if (abs(leg_ik_from_ankle_local_pos.x()) > leg_ik_height or abs(leg_ik_from_ankle_local_pos.z()) > leg_ik_height or leg_ik_bf.position.y() > leg_ik_height / 2) \
and leg_ik_from_leg_local_pos.length() > leg_ik_height * 2:
logger.warning(f"○{fno}, {direction}足: 足首から{leg_ik_from_ankle_local_pos.to_log()}, 足から{leg_ik_from_leg_local_pos.to_log()} ({leg_ik_global_pos.to_log()})")

# # 足FKの捩り成分を制限する
# # leg_fk_x_degree = min(90, max(0, leg_fk_x_qq.toDegreeSign(leg_fk_local_x_axis)))
# leg_fk_x_degree = 180
# new_leg_fk_x_qq = MQuaternion.fromAxisAndAngle(leg_fk_x_qq.vector(), leg_fk_x_degree)

# copy_leg_fk_bf = leg_fk_bf.copy()
# copy_leg_fk_bf.rotation = MQuaternion()
# motion.regist_bf(copy_leg_fk_bf, leg_fk_bone_name, fno)

# copy_knee_bf = knee_bf.copy()
# copy_knee_bf.rotation = MQuaternion()
# motion.regist_bf(copy_knee_bf, knee_bone_name, fno)

# logger.warning(f" {fno}, {direction}足捩り: axis: {leg_fk_local_x_axis.to_log()}, x: {round(leg_fk_x_qq.toDegreeSign(leg_fk_local_x_axis), 2)} -> {round(new_leg_fk_x_qq.toDegreeSign(leg_fk_local_x_axis), 2)}")

# before_leg_fk_x_qq, _, _, _ = MServiceUtils.separate_local_qq(fno, leg_fk_bone_name, leg_fk_bf.rotation, leg_fk_local_x_axis)

# IK計算実行
MServiceUtils.calc_IK(model, leg_fk_links, motion, fno, leg_ik_global_pos, leg_fk2ik_links, max_count=20)

# IK計算後のFK角度に捩り分を加算する
leg_twist_after_fk_bf = motion.calc_bf(leg_twist_fk_bone_name, fno)
leg_fk_after_bf = motion.calc_bf(leg_fk_bone_name, fno)
leg_fk_after_bf.rotation *= leg_twist_after_fk_bf.rotation
motion.regist_bf(leg_fk_after_bf, leg_fk_bone_name, fno)
logger.warning(f" {fno}, {direction}足: leg_twist_after_fk_bf: {leg_twist_after_fk_bf.rotation.data()}, ({round(leg_twist_after_fk_bf.rotation.toDegreeSign(leg_fk_local_x_axis), 2)})")

# # _, after_leg_fk_y_qq, after_leg_fk_z_qq, _ = MServiceUtils.separate_local_qq(fno, leg_fk_bone_name, leg_fk_after_bf.rotation, leg_fk_local_x_axis)

# # before_leg_fk_x_degree = before_leg_fk_x_qq.toDegreeSign(leg_fk_local_x_axis)
# # after_leg_fk_x_degree = max(-45, min(45, before_leg_fk_x_degree))

# # # Xの捩りを元に戻す
# # leg_fk_after_bf.rotation *= MQuaternion.fromAxisAndAngle(leg_fk_local_x_axis, after_leg_fk_x_degree)
# # motion.regist_bf(leg_fk_after_bf, leg_fk_bone_name, fno)
# # logger.warning(f" {fno}, {direction}足: before_leg_fk_x_qq: {before_leg_fk_x_qq.data()}, ({round(before_leg_fk_x_degree, 2)} -> {round(after_leg_fk_x_degree, 2)})")

# # IK計算実行(Yが決まった後に全体)
# MServiceUtils.calc_IK(model, leg_fk_links, motion, fno, leg_ik_global_pos, leg_fk2ik_links, max_count=20)

# # IK計算後のFK角度
# leg_fk_after_bf = motion.calc_bf(leg_fk_bone_name, fno)
# leg_fk_after_x_qq, leg_fk_after_y_qq, leg_fk_after_z_qq, leg_fk_after_yz_qq = MServiceUtils.separate_local_qq(fno, leg_fk_bone_name, leg_fk_after_bf.rotation, leg_fk_local_x_axis)

# # IK計算後のFK角度
# knee_after_bf = motion.calc_bf(knee_bone_name, fno)
# knee_x_qq, knee_y_qq, knee_z_qq, knee_yz_qq = MServiceUtils.separate_local_qq(fno, knee_bone_name, knee_bf.rotation, knee_local_x_axis)
# knee_after_x_qq, knee_after_y_qq, knee_after_z_qq, knee_after_yz_qq = MServiceUtils.separate_local_qq(fno, knee_bone_name, knee_after_bf.rotation, knee_local_x_axis)

# # # IK計算後の足FKの捩り成分を制限する
# # new_leg_fk_x_degree = min(20, max(-45, leg_fk_after_x_qq.toDegreeSign(leg_fk_local_x_axis)))
# # new_leg_fk_x_qq = MQuaternion.fromAxisAndAngle(leg_fk_after_x_qq.vector(), new_leg_fk_x_degree)
# # logger.warning(f" {fno}, {direction}足捩り: x: {round(leg_fk_after_x_qq.toDegreeSign(leg_fk_local_x_axis), 2)} -> {round(new_leg_fk_x_degree, 2)}")

# # # Zの捩りはIK計算後のものを採用する
# # leg_fk_after_bf.rotation = leg_fk_after_y_qq * leg_fk_after_x_qq * leg_fk_after_z_qq

# # 足FKのbf
# logger.warning(f" {fno}, {direction}足: x: {round(leg_fk_x_qq.toDegreeSign(leg_fk_local_x_axis), 2)}, y: {round(leg_fk_y_qq.toDegreeSign(leg_fk_local_y_axis), 2)}, z: {round(leg_fk_z_qq.toDegreeSign(leg_fk_local_z_axis), 2)} → x: {round(leg_fk_after_x_qq.toDegreeSign(leg_fk_local_x_axis), 2)}, y: {round(leg_fk_after_y_qq.toDegreeSign(leg_fk_local_y_axis), 2)}, z: {round(leg_fk_after_z_qq.toDegreeSign(leg_fk_local_z_axis), 2)}")
# logger.warning(f" {fno}, {direction}ひざ: x: {round(knee_x_qq.toDegreeSign(knee_local_x_axis), 2)}, y: {round(knee_y_qq.toDegreeSign(knee_local_y_axis), 2)}, z: {round(knee_z_qq.toDegreeSign(knee_local_z_axis), 2)} → x: {round(knee_after_x_qq.toDegreeSign(knee_local_x_axis), 2)}, y: {round(knee_after_y_qq.toDegreeSign(knee_local_y_axis), 2)}, z: {round(knee_after_z_qq.toDegreeSign(knee_local_z_axis), 2)}")
else:
logger.warning(f"-{fno}, {direction}足: 足首から{leg_ik_from_ankle_local_pos.to_log()}({round(leg_ik_from_ankle_local_pos.length(), 4)}), 足から{leg_ik_from_leg_local_pos.to_log()}({round(leg_ik_from_leg_local_pos.length(), 4)})")

# # 後で削除しておく
# del motion.bones[leg_twist_fk_bone_name]

new_file_path = reader.file_path.replace(".vmd", f"_FK_{datetime.now():%Y%m%d_%H%M%S}.vmd")

data_set = MOptionsDataSet(motion, model, model, new_file_path)
writer = VmdWriter(data_set)
writer.write()

self.assertTrue(True)

logger.warning(f"出力終了: {new_file_path}")


class CameraLengthTest(unittest.TestCase):

def test_camera_length(self):
Expand Down

0 comments on commit 151c79e

Please sign in to comment.