そういう、モデルなんです。

ビジネスモデル、3Dモデル、設計図、模型などの現状と動向を考察、関連書籍の紹介

Blender で13種類の典型的な表情モーションをいい加減だけど一応自動生成して「シェイプキーとして適用」で保存する Python スクリプト

Blender にインポートした Sims4人物モデルのリグ(ボーン)を使用して、VRMアバターで普通は必要となるであろう典型的な表情を自動的に作成する Blender 3.2 Python スクリプトを考えた。

GitHub - tombi-aburage/Sims4VRMAvatar : shapeedit.py

Blender の Script メニューにある Python コンソールへのコピペ、またはテキストエディタへコピペして引数を変えて実行する。

実行する前の前提としては:

  • Sims 4 人物モデルのメッシュオブジェクトのモディファイアーとして、Sims 4 のリグ(アーマチュア)rig が割り当てられている
  • Sims 4 のリグ(アーマチュア)rig を選択して、ポーズモードにしてある
  • import bpy と import math を先に実行してある

など

まばたき左のみ Fcl_EYE_Close_L

bpy.data.objects['rig'].pose.bones['b__L_UpLid__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__L_UpLid__'].rotation_euler.rotate_axis('Z',math.radians(25))

まばたき右のみ Fcl_EYE_Close_R

bpy.data.objects['rig'].pose.bones['b__R_UpLid__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__R_UpLid__'].rotation_euler.rotate_axis('Z',math.radians(25))

まばたき Fcl_EYE_Close

bpy.data.objects['rig'].pose.bones['b__L_UpLid__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__L_UpLid__'].rotation_euler.rotate_axis('Z',math.radians(25))
bpy.data.objects['rig'].pose.bones['b__R_UpLid__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__R_UpLid__'].rotation_euler.rotate_axis('Z',math.radians(25))

怒り Fcl_ALL_Angry

bpy.data.objects['rig'].pose.bones['b__L_InBrow__'].location.x -= 0.02
bpy.data.objects['rig'].pose.bones['b__R_InBrow__'].location.x -= 0.02
bpy.data.objects['rig'].pose.bones['b__L_UpLip__'].location.x += 0.01
bpy.data.objects['rig'].pose.bones['b__R_UpLip__'].location.x += 0.01
bpy.data.objects['rig'].pose.bones['b__UpLip__'].location.x += 0.01
bpy.data.objects['rig'].pose.bones['b__LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__L_LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__R_LoLip__'].location.x += 0.005

楽しい Fcl_ALL_Fun

bpy.data.objects['rig'].pose.bones['b__L_Mouth__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__R_Mouth__'].location.x += 0.005

喜び Fcl_ALL_Joy

bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_euler.rotate_axis('Z',math.radians(-5))
bpy.data.objects['rig'].pose.bones['b__L_Mouth__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__R_Mouth__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__L_LoLid__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__L_LoLid__'].rotation_euler.rotate_axis('Z',math.radians(-10))
bpy.data.objects['rig'].pose.bones['b__R_LoLid__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__R_LoLid__'].rotation_euler.rotate_axis('Z',math.radians(-10))

哀しみ Fcl_ALL_Sorrow

bpy.data.objects['rig'].pose.bones['b__L_InBrow__'].location.x += 0.01
bpy.data.objects['rig'].pose.bones['b__R_InBrow__'].location.x += 0.01
bpy.data.objects['rig'].pose.bones['b__L_MidBrow__'].location.x -= 0.01
bpy.data.objects['rig'].pose.bones['b__R_MidBrow__'].location.x -= 0.01
bpy.data.objects['rig'].pose.bones['b__L_OutBrow__'].location.x -= 0.01
bpy.data.objects['rig'].pose.bones['b__R_OutBrow__'].location.x -= 0.01
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_euler.rotate_axis('Z',math.radians(-5))
bpy.data.objects['rig'].pose.bones['b__L_Mouth__'].location.x -= 0.005
bpy.data.objects['rig'].pose.bones['b__R_Mouth__'].location.x -= 0.005

い Fcl_MTH_I

bpy.data.objects['rig'].pose.bones['b__L_UpLip__'].location.x += 0.002
bpy.data.objects['rig'].pose.bones['b__R_UpLip__'].location.x += 0.002
bpy.data.objects['rig'].pose.bones['b__UpLip__'].location.x += 0.002
bpy.data.objects['rig'].pose.bones['b__LoLip__'].location.x -= 0.002
bpy.data.objects['rig'].pose.bones['b__L_LoLip__'].location.x -= 0.002
bpy.data.objects['rig'].pose.bones['b__R_LoLip__'].location.x -= 0.002

あ Fcl_MTH_A

bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_euler.rotate_axis('Z',math.radians(-5))

え Fcl_MTH_E

bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_euler.rotate_axis('Z',math.radians(-5))

お Fcl_MTH_O

bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_euler.rotate_axis('Z',math.radians(-10))
bpy.data.objects['rig'].pose.bones['b__LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__L_LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__R_LoLip__'].location.x += 0.005

う Fcl_MTH_U

bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_mode='XYZ'
bpy.data.objects['rig'].pose.bones['b__Jaw__'].rotation_euler.rotate_axis('Z',math.radians(-5))
bpy.data.objects['rig'].pose.bones['b__LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__L_LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__R_LoLip__'].location.x += 0.005
bpy.data.objects['rig'].pose.bones['b__L_Mouth__'].location.z -= 0.002
bpy.data.objects['rig'].pose.bones['b__R_Mouth__'].location.z += 0.002

通常 Fcl_ALL_Neutral

(何もしない)

上記の操作を手動で行う場合の作業イメージ

tombi-aburage.hatenablog.jp

  • いよいよ、顔面の表情モーション(モーフ)に取り掛かる

以降を参照のこと。スクリプトにする前は手作業でやっていた。

カスタマイズするときに使えるかもしれない設計シート

上記スクリプトを作成するにあたり、Excel シート上に記録しながら設計した。

tombi-aburage.gumroad.com