============ ボーンの表示 ============ 読み取ったデータからまずはボーンの頂点配列を作って表示してみる。 <%= source_view('src/PMDBone.py') %> スケルトンの表示に必要な木構造と各ボーンの親ボーンからの相対位置のみをコピーして表示してみる。 PMDボーンにBVHモーションを流し込んでみる ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pmdモデルなのでvmdモーションを流し込めばいいのだが、標準のスケルトンはIKがついているのでそれを解決してからにしないと足などがまともに動かない。もうひとつvmdのモーションはキーフレームを採用していて間をベジェ補間しているのでそれもひと手間かかる。とりあえずBVHのモーションで試してみよう。ただし、PMDとBVHではスケルトンの構造とボーンの命名が違うのでそれに対処する必要がある。 今回使ったBVHのスケルトン ------------------------- bvhloader.pyに直接引数を与えると木構造を表示するようにしてある :: Hips 0.000000 35.647600 0.000000 Chest 0.000001 12.147400 0.000000 Neck -0.000000 11.804900 0.000000 Head -0.000000 3.970430 0.000000 > 0.000000 9.264330 0.000000 LeftCollar -0.000000 11.804900 0.000000 LeftUpArm 8.024650 0.000000 -0.000007 LeftLowArm 11.118800 0.000000 -0.000008 LeftHand 9.988660 0.000000 -0.000007 > 5.851260 0.000000 -0.000004 RightCollar -0.000000 11.804900 0.000000 RightUpArm -8.024650 0.000000 -0.000001 RightLowArm -11.118800 0.000000 0.000000 RightHand -9.988660 0.000000 0.000000 > -5.851260 0.000000 0.000000 LeftUpLeg 3.912320 0.000000 0.000000 LeftLowLeg 0.000000 -16.654500 0.000002 LeftFoot 0.000000 -15.447000 0.000002 > 0.037397 -3.865870 6.717130 RightUpLeg -3.912320 0.000000 -0.000000 RightLowLeg 0.000000 -16.654500 0.000002 RightFoot 0.000000 -15.447000 0.000002 > 0.034208 -3.883120 6.707190 初音ミクVer2のスケルトン ------------------------ :: センター (center) +(upper body) | +(neck) | | +(head) | | +(eye_L) | | | +(eyelight_L) | | | | +(bone128) | | | +(bone095) | | +(eye_R) | | | +(eyelight_R) | | | | +(bone129) | | | +(bone096) | | +(hair1_L) | | | +(hair2_L) | | | +(hair3_L) | | | +(hair4_L) | | | +(hair5_L) | | | +(hair6_L) | | | +(hair7_L) | | +(hair1_R) | | | +(hair2_R) | | | +(hair3_R) | | | +(hair4_R) | | | +(hair5_R) | | | +(hair6_R) | | | +(hair7_R) | | +(eyes) | | | +(bone117) | | +(front hair1) | | | +(bone125) | | +(front hair2) | | | +(bone126) | | +(front hair3) | | | +(bone127) | | +(bone094) | +(necktie1) | | +(necktie2) | | +(necktie3) | | +(necktie4) | +(shoulder_L) | | +(arm_L) | | +(arm twist_L) | | | +(elbow_L) | | | | +(wrist twist_L) | | | | | +(wrist_L) | | | | | | +(thumb1_L) | | | | | | | +(thumb2_L) | | | | | | | +(bone100) | | | | | | +(fore1_L) | | | | | | | +(fore2_L) | | | | | | | +(fore3_L) | | | | | | | +(bone101) | | | | | | +(middle1_L) | | | | | | | +(middle2_L) | | | | | | | +(middle3_L) | | | | | | | +(bone102) | | | | | | +(third1_L) | | | | | | | +(third2_L) | | | | | | | +(third3_L) | | | | | | | +(bone103) | | | | | | +(little1_L) | | | | | | | +(little2_L) | | | | | | | +(little3_L) | | | | | | | +(bone104) | | | | | | +(bone099) | | | | | +(bone131) | | | | +(sleeve_L) | | | | +(bone098) | | | +(bone130) | | +(bone134) | | +(bone135) | | +(bone136) | +(shoulder_R) | +(arm_R) | +(arm twist_R) | | +(elbow_R) | | | +(wrist twist_R) | | | | +(wrist_R) | | | | | +(thumb1_R) | | | | | | +(thumb2_R) | | | | | | +(bone109) | | | | | +(fore1_R) | | | | | | +(fore2_R) | | | | | | +(fore3_R) | | | | | | +(bone110) | | | | | +(middle1_R) | | | | | | +(middle2_R) | | | | | | +(middle3_R) | | | | | | +(bone111) | | | | | +(third1_R) | | | | | | +(third2_R) | | | | | | +(third3_R) | | | | | | +(bone112) | | | | | +(little1_R) | | | | | | +(little2_R) | | | | | | +(little3_R) | | | | | | +(bone113) | | | | | +(bone108) | | | | +(bone133) | | | +(sleeve_R) | | | +(bone107) | | +(bone132) | +(bone137) | +(bone138) | +(bone139) +(lower body) | +(waist accessory) | | +(bone097) | +(front skirt_L) | | +(bone105) | +(back skirt_L) | | +(bone106) | +(leg_L) | | +(knee_L) | | +(ankle_L) | | +(toe_L) | +(front skirt_R) | | +(bone114) | +(back skirt_R) | | +(bone115) | +(leg_R) | | +(knee_R) | | +(ankle_R) | | +(toe_R) | +(bone093) +(necktie IK) | +(bone118) +(hair IK_L) | +(bone119) +(hair IK_R) | +(bone120) +(bone116) 左足IK (leg IK_L) +(toe IK_L) | +(bone123) +(bone121) 右足IK (leg IK_R) +(toe IK_R) | +(bone124) +(bone122) ボーン名をマッピングする ------------------------ 全然構成が違うんだけどとりあえずマッピングする。 BVH -> PMD への変換だけを作ればいいので手間はたいしたことは無い。 右手系と左手系とどっちが上なのか -------------------------------- ここで複数のフォーマット間でデータを運用するときにぶつかる、ものによって採用している座標系が違うという問題があらわれる。 三次元の座標系は、どの座標を上下前後左右に割り当てるかで流派がありそれぞれのフォーマットは独自の流派を持つ。 PMDは、右:X, 上:Y, 奥:Zの座標系(DirectX)を採用していて OpenGL(MQOも)は、右:X, 上:Y, 手前:Zの座標系を採用している。 そのため読み込んだ後ボーンのZ座標の正負を入れ替える処理をいれている。 大きくDirectX派(左手系)とOpenGL派(右手系)という方向性と、 CAD派(Z軸が上。たぶん平面図を立体化するという発想)と非CAD派(Y軸が上。モニタに対する奥行きがZという発想)の2軸の組み合わせがある。複数環境を混ぜる場合は注意が必要。 .. note:: BVHの座標系に関してはよくわからない <%= source_view('src/PMDBoneBVH.py') %> .. note:: class=memo>ToDo: 移動要素の調整