Homeマシシ 

 

pmxファイルの作成

blenderからMikuMikuDance用のpmxファイルを作成する方法をざっくりと記載


ソフトウェアの準備

Blender2.71をインストール (Pythonは不要)

続いてデータ変換用のアドオンをダウンロードしてインストール
 blender2pmx または Blender2Pmxe(かがやすさんの改造版)
 ※2015.12.15 Blender2.76bだとエクスポート時にtest.blendの場合test.xmlをロード出来ない不具合あり
   ファイル名取得部分の仕様が変わった?test.blendの場合test.pmx.xmlにすると読み込める

「C:\Program Files\Blender Foundation\Blender\2.71\scripts\addons」にフォルダごと入れる。
(ZIPファイルをInstall from Fileで選んでもコピーされる)

Blenderを起動してFileからUserPreferencesを選択

AddonsタブからInport-Exportを選択

MMD PMX Formatを一覧から探しチェックを付けてSave As Defaultボタンを押す


入出力

ファイル>インポート>PMX file for MMD(.pmx)
  ・インポートするとxmlファイルがpmdと同じフォルダ内に生成される

ファイル>エクスポート>PMX file for MMD(.pmx)
 ・エクスポートする際は同名のxmlと各種テクスチャを同じフォルダに配置(例:test.blend・test.xml・eye.bmp)
 ・書き出し時はArmatureを選択してから行う。
 ・pmdエクスポータと座標系・モデルサイズ・色が違うのでpmd時に使ったデータを流用する場合は注意


XMLファイル内の説明

※exporter 1.24からindexの番号処理が不要になり、並び順で処理されるように仕様がかわりました。
  (これでつらい番号振り分けから開放されます)

materials
xml PMDE 説明
b_name   Blender上のマテリアル名
both 両面描写 pmd時の透明度0.999と同じ
ground_shadow 地面影 地面に影を落とす
drop_shadow セルフ影マップ 自分に影を落とす(他の素材)
on_shadow セルフ影 自分に影を落とす(同一素材)
on_edge エッジ(輪郭) 輪郭線の表示
edge_size エッジ(輪郭) 輪郭線の太さ
toon toon toon指定0でtoon01.bmp、-1だとtoon無し
use_systemtoon   ユーザー作成toon使用toon値にファイル名指定
edge_color エッジ(輪郭) 輪郭線の色、Aは透明度

bones
xml PMDE 説明
b_name   Blender上のボーン名
name ボーン名 ボーン名(日)
name_e ボーン名 ボーン名(英)
rotatable 回転 回転する
movable 移動 移動する
ik IK IKボーンの場合1
visible 表示 表示する
operational 操作 操作する
target Target b_name指定
add_rot 回転+ ターゲットの回転に連動
add_move 移動+ ターゲットの移動に連動
power 付与率 連動具合(1で100%)
fixed_axis 軸制限 捩ボーン
local_axis ローカル軸 ローカル軸を作成する

constraints
body_Abody_Bは剛体のindex番号でrigid_bodiesの最初の行を0として数えた番号になる。


仕様

モデルサイズは1BU=1ミクセルで出力される
 ・1ミクセルはMMDの1マスでミクの身長から1ミクセルは40cmと推測される
  ・アクセでDirectX Exporterを使いXファイルを出すと1BU=2ミクセルになるため注意

四角面や多角形はエクスポートすると三角面に変換されるため変に変換される箇所は先に三角にしておく(多角面も同様)

マテリアルは色(Col)→Diffuse、光沢(Spe)→Specularになる。
Ambientはカスタムプロパティでプロパティ名「Ambient」を追加、プロパティ値にRGBの値を「[0.5, 0.5, 0.5]」のように入れる
(ない場合は自動計算された値が入る)
画面上の色から取得する場合はPMDColorCalcなんかを使うと便利
作者fooberさんのサイトでは公開されてない&にゃっぽん終了のため現在は直リンのみ→PMDColorCalc20100307.zip
※MMDの色についての解説動画→sm20686014

エクスポート時に面UVから頂点UVに変換されるためくっついていないUVマップの境界は頂点が2倍になる

blender上では法線が裏返しでも見えるがMMD上で片面の場合は見えないため外向きになるように修正する

物理設定はBlender上で出来ないがインポートした際に剛体とジョイントはXMLに保存されて出力時に一緒に出力される

MMDのボーン名は15バイト(半角15文字、全角7文字)まででそれ以上の場合は、
エクスポータでPMDが出来たとしても MMDで読み込んだ際にMMDが落ちる

SDEFは非対応(インポート時はBDEFに変換される)
※SDEFのまま取り込むとウエイトがおかしくなる不具合があるためPMDEでBDEFに変えてからインポート

素材モーフ・UVモーフ・グループモーフなどは非対応なので編集の際はPMXEでcsvファイルに保存しておくと良い

生成されるファイル(xml、pmx)の上書き確認はないので注意(同名ファイルは強制上書き)

スフィアはテスクチャの2行目に追加する、テクスチャがなくスフィアのみの場合は1行目にタイプなしの空テクスチャを入れる
ブレンドが[ミックス]で[乗算](旧sph)、[追加]で[加算](旧spa)になる

ローカル座標値非対応(ローカル座標を使うかどうかの判定のみ対応)

ボーン先端が設定されていないボーン(捩ボーンなど)はインポート時に無理やりBlender用のボーンになり軸がずれるので修正する

ボーンの出力順はxmlを変更してもその順番で並ばない(どうもアウトライナーの順番で出力されている様子)


不具合や注意点など(2014年6月現在)

ボーンを選択してからエクスポートを実行しないとボーンが出力されない。
(ボーンを選択してもボーンが出力されない場合はボーンの編集モードでスクリプトを実行すると出る場合がある。)

マテリアルの設定されていないオブジェクトがあると書き出しに失敗する。
 IndexError:bpy_prop_collection[index]:index 0 out or range, size0

頂点がないオブジェクトが存在しているとエラーになる。

どこにも割り当てられていないマテリアルがあるとエラーになる。

インポート時ShapeKeysがbasis以外になっているため編集する際は注意

回転のみのボーンはポーズモードでボーンのlocationのXYZをロックすると回転のみになる
(ただしxmlでmovable値指定の場合はそちら優先)

テクスチャのファイルパスは無しか下層フォルダでないと反映されないので注意

取り込み時にテクスチャパスが別ドライブにあると出力時にエラーになる

IKの角度制限はInversKinematicsで設定可能だがYがZにZがYに反映される不具合あり
(BlenderのXYZを単純にMMDのXYZに入れてると思われる)

ローカル軸がおかしくなる不具合があるためPMDEで修正必要
(MMDはボーンの向きが+Xになるはずが出力したのは-Yになる)

IKのLoop値はIKボーンのCustom Propertiesで「IKLimit」「IKLoops」という値を作成して設定する
(例:足IKLimit=2 IKLoops=40 つま先IKLimit=4 IKLoops=3 )

モーフ<morphs>と表示名<labels>が一致しないとおかしくなる不具合あり(ボーンも同じ)

モーフ数が多いと処理できない

グループモーフがあるとインポート出来ない(削除すれば取り込み出来る)

物理設定をxml上で編集する場合は<rigid_bodies>のindexを<constraints>のbody_A・body_Bに割り当てればよいが
<rigid_bodies>のindexが8でindex0〜7がない場合はbody_A=8ではなくbody_A=0になるので注意
(※rigid_bodiesのindexを0から振りなおしておけばまず問題ない)


出力後PMXEで行う作業

ボーンのローカル座標設定
  肩、腕、ひじ、手首それぞれ選択してローカル軸ボタンをONしたの「>」を押す

SDEF化
  対象の頂点を選んで
  編集>ウエイト関連>選択頂点をSDEF設定
  ※ただし親子でボーンが繋がってない場所はSDEF化されない

UVモーフ
  モーフリストで右クリック>新規モーフ追加>頂点/UV
  モーフ編集画面で種類を頂点からUVへ
  子窓の「絞」から「頂点/材質マスキング」を開き「材質」で変更する材質のみチェック
  画面で頂点を範囲指定
  子窓の「動」から「オブジェクト操作」を開き「UV」タブの移動Vを押したままマウスを動かす(Vが縦、Uが横)
  モーフ編集に戻り新規追加ボタンを押す(続けて作成はいいえ)

材質モーフ
  モーフリストで右クリック>新規モーフ追加>材質
  材質タブで変更したい材質を選択し右クリック>indexコピー
  モーフタブに戻り先ほど作成した材質モーフのオフセットの下にある空欄を右クリック>「indexコピーから追加」
  編集ボタンを押して編集

ボーンモーフ
  TransformViewでポーズさせて
  編集>現在の変形状態 で新規ボーンモーフ追加
  ※MMDでポーズデータ(vpd)を作成して、そのファイルをTransformViewにDDする手もある

モーフのグループ化
  複数のモーフを選んで右クリック>グループモーフにまとめる


小ネタ

アイテムなどを消す方法その1:体の中に隠す
  袖やブーツなどを消したい場合ただ小さくするだけだと動かした際にウエイトの関係で飛び出してしまう
  足首とひざの2種類のウエイトがある頂点を隠したい場合は足首とひざボーンの接続部分に納めると変形の影響がほとんど無い状態になる

アイテムなどを消す方法その2: 材質モーフ
  材質モーフの加算で素材色のAを「-1」エッジA「-1」
  ※SSAOなどのエフェクトは透明材質でも影をつくるのでエフェクトを利用する場合は対象の材質をMMEで対象外にする

リボンなどの物理をつける箇所を作成する場合のコツ
  最初から垂れた状態で形状を作ってしまうと剛体設定で角度制限などが厳しくなり動きがぎこちなくなる
  無重力状態の位置で作成して剛体で垂れた状態になるようにすると動きのある剛体設定が出来る

モーフを非表示化する
  PMDEでモーフを選択してCtrl+C、メモなどに貼り付けて2行目の後ろから2個目を0にする
  その内容をすべて選択してCtrl+C、元のモーフにCtrl+Vで貼り付ける
 例:「Morph,"あ","a",3,1」→ 「Morph,"あ","a",0,1」
 エクスポータで扱えるモーフの場合はXMLで0にしておけば非表示で出力される
 ※しえらさんがPMDEのプラグインを作成されました→【配布】モーフ非表示化プラグイン と初音の花道

同じ材質で半透明が重なった際のガタガタ表示を直す方法
 面選択で縦に面を一列選択して
 メッシュ>要素をソート>選択部位>面
 で前(若い番号)に移動する
 反転にチェックした場合は後ろに移動する
 髪の房なんかは真ん中から左右に展開していくと良い
  ※材質を片面にすれば良いというのを聞いたが関係無いみたい

出力されるボーンの並びを変える
  MMDへ出力される順番はアウトライナー順(xmlの並びが無視されてる?)のようなので以下の方法で並び準を直す
  (基本直さなくてよいが両目などは目より上にいる必要があるため)

  @編集モード>アウトライナーで並べ替えたいボーン選択
  Aプロパティ>ボーンで親を解除
  Bオブジェクトモードに戻ったあと編集モードに戻す(編集モードのままだと並び準を覚えているため変えられない)
  C親を再設定で親ボーンの並びの一番下に来る


export_pmx.py(ver1.25)のカスタマイズ(上級者向け?)

ボーン先が「ボーン名_」となるのを「ボーン名先」「左ボーン名先」「右ボーン名先」で出力する方法
  bone_stack.append((arm_obj.name,bone.name + "_",bone.name))
 
  # bone_stack.append((arm_obj.name,bone.name + "_",bone.name))
 if bone.name.endswith('_L'):
  bone_stack.append((arm_obj.name,'\u5de6' + bone.name.rstrip('_L')+ "\u5148",bone.name))
 else:
  if bone.name.endswith('_R'):
   bone_stack.append((arm_obj.name,'\u53f3' + bone.name.rstrip('_R')+ "\u5148",bone.name))
  else:
   bone_stack.append((arm_obj.name,bone.name + "\u5148",bone.name))

  pmx_bone.ChildIndex = bone_index.get(bone.name + "_",-1)
  ↓

  # pmx_bone.ChildIndex = bone_index.get(bone.name + "_",-1)
 if bone.name.endswith('_L'):
  pmx_bone.ChildIndex = bone_index.get('\u5de6' + bone.name.rstrip('_L')+ "\u5148",-1)
 else:
  if bone.name.endswith('_R'):
   pmx_bone.ChildIndex = bone_index.get('\u53f3' + bone.name.rstrip('_R')+ "\u5148",-1)
  else:
   pmx_bone.ChildIndex = bone_index.get(bone.name + "\u5148",-1)

「ボーン名_L」「ボーン名_R」をxml指定無しに「左ボーン名」「右ボーン名」で出力する方法
 pmx_bone.Name = bone.name
 ↓
 # pmx_bone.Name = bone.name
  if bone.name.endswith('_L'):
  pmx_bone.Name = '\u5de6' + bone.name.rstrip('_L')
 else:
  if bone.name.endswith('_R'):
   pmx_bone.Name = '\u53f3' + bone.name.rstrip('_R')
  else:
   pmx_bone.Name = bone.name

2009/02/23