「ユーザーブロマガ」サービスの終了(10月7日を予定)にあたり、残したいユーザーブロマガ記事への投票を受け付けています

  • PMDEプラグインの作り方 ボーン操作編6

    2013-03-13 20:482

    PMDEプラグインの作り方 ボーン操作編6

    プラグインとはいえ普通にC#なので記述の仕方はいろいろありますが、わかりやすくするために記述方法に制限をかけています。必ずこのやり方でないといけないわけではありませんのでご注意ください。

    前回と同様にこのサンプルプラグインプロジェクトファイル(http://bowlroll.net/up/dl15339)を元に説明しますので必ずDLしてください。
    この中にはボーン操作に必要な機能をあらかじめ入れてあります。説明もそれに沿った形で説明します。また、このプロジェクトファイルの内容を流用してプラグインを作成することは問題ありません。
    以下ボーン操作とそのコードを記述します。前回と同様にサンプルプロジェクトファイルにこぴぺすれば動作すると思います。


    1.表示枠のIndexを取得します。
    //ボーン表示枠の名前
    string BoneFrameName="その他";
    //表示枠Index
    int Index=-1;
    //表示枠を順番にチェックします。
    for (int i = 0; i < this.PMX.Node.Count; i++)
    {
    //表示枠の名前が同じものがあればIndexにiを代入します。

    if (this.PMX.Node[i].Name == BoneFrameName)
    {
    Index = i;
    }

    }

    こちらもボーン同様にGetFramIndexという関数にしてあります。

    2.表示枠内の要素Indexを取得する。
    //ボーン表示枠の名前
    string BoneFrameName="その他";
    //ボーン表示枠から取得したいボーンの名前
    string BoneName="前髪1";
    //表示枠内Index
    int Index=-1;
    //表示枠Indexを取得します

    int i = this.GetFrameIndex(BoneFrameName);
    if (i >= 0)
    {
    //表示枠を取得します。

    IPXNode node = (IPXNode)this.PMX.Node[i];
    //ボーンIndexを取得します。

    int j = this.GetBoneIndex(BoneName);
    if (j >= 0)
    {
    IPXBone Bone = (IPXBone)this.PMX.Bone[j];
    //表示枠内のアイテムを順番にチェックします。

    for (int k = 0; k < node.Items.Count; k++)
    {
    //表示枠内のアイテムと比較して同じだったらIndexにiの値を代入します。

    if (node.Items[i].BoneItem.Bone == Bone)
    {
    Index= k;
    }
    }
    }

    こちらもボーン同様にGetBoneFrameItemIndexという関数にしてあります。


    3.ボーン表示枠を作成します。
    例)「その他」というボーン表示枠を追加します。

    //ボーン表示枠の名前
    string BoneFrameName="その他";
    //ボーン表示枠の空箱作成
    IPXNode node=PEStaticBuilder.Pmx.Node();
    //空枠に名前をつける
    node.Name=BoneFrameName;
    //表示枠に追加する。
    this.PMX.Node.Add(node);

    もしくは

    //テンプレートプロジェクトを使う場合
    //ボーン表示枠の名前
    string BoneFrameName="その他";
    //表示枠に追加する。
    this.AddBoneFrame(BoneFrameName);

    以上でボーン表示枠に新しい表示枠を追加できます。

    4.ボーン表示枠にボーンを追加します。
    例)「その他」というボーン表示枠に「前髪1」ボーンを追加します。

    //ボーン表示枠の名前
    string BoneFrameName="その他";
    //ボーン表示枠に追加したいボーンの名前
    string BoneName="前髪1";
    //ボーン表示枠のIndexを取得
    int i=this.GetFrameIndex(BoneFrameName,1);
    //ボーンのIndexを取得
    int j=this.GetBoneIndex(BoneName,1);
    //表示枠を取得
    IPXNode node=(IPXNode)this.PMX.Node[i];
    //表示枠の中の空箱を作成
    IPXBoneNodeItem NodeItem=PEStaticBuilder.Pmx.BoneNodeItem();
    //空箱の中にボーンを入れる。
    NodeItem.Bone=this.PMX.Bone[j];
    //表示枠の中に追加
    node.Items.Add(NodeItem);

    もしくは

    //テンプレートプロジェクトを使う場合
    //ボーン表示枠の名前
    string BoneFrameName="その他";
    //ボーン表示枠に追加したいボーンの名前
    string BoneName="前髪1";
    //ボーン表示枠にボーンを追加する。
    this.AddBoneFrameItem(BoneFrameName,BoneName);

    5.ボーン表示枠の中のボーンを削除します。
    //ボーン表示枠の名前
    string BoneFrameName = "その他";
    //ボーン表示枠から削除したいボーンの名前
    string BoneName = "前髪1";
    //表示枠を取得
    int j=this.GetFrameIndex(BoneFrameName;
    IPXNode BoneFrame = (IPXNode)this.PMX.Node[j)];
    int k=this.GetBoneIndex(BoneName);
    IPXBone Bone = (IPXBone)this.PMX.Bone[k];
    //ボーン表示枠の中から
    for (int i=0;i<BoneFrame.Items.Count;i++){
    if(BoneFrame.Items[i].isBone)
    {
    if (BoneFrame.Items[i].BoneItem.Bone == Bone)
    {
    BoneFrame.Items.Remove(BoneFrame.Items[i]);
    }
    }
    }

    もしくは

    //テンプレートプロジェクトを使う場合
    //ボーン表示枠の名前
    string BoneFrameName = "その他";
    //ボーン表示枠から削除したいボーンの名前
    string BoneName = "前髪1";
    //表示枠を取得
    int i=this.GetFrameIndex(BoneFrameName);
    IPXNode BoneFrame = (IPXNode)this.PMX.Node[i];
    int j=this.GetBoneFrameItemIndex(BoneFrameName, BoneName);
    BoneFrame.Items.Remove(BoneFrame.Items[j]);

    6.ボーン表示枠を削除します。
    //ボーン表示枠の名前
    string BoneFrameName = "その他";
    //表示枠を取得
    int i=this.GetFrameIndex(BoneFrameName);
    IPXNode BoneFrame = (IPXNode)this.PMX.Node[i];
    //表示枠の中身をクリアします。
    BoneFrame.Items.Clear();
    //表示枠を削除します。
    this.PMX.Node.Remove(BoneFrame);

    7.ボーン表示枠のどこかに入っているボーンを表示枠から削除します。
    //ボーン表示枠から削除したいボーンの名前
    string BoneName = "前髪1";
    //ボーンを取得します。
    IPXBone Bone = (IPXBone)this.PMX.Bone[this.GetBoneIndex(BoneName)];
    for (int i=0;i<this.PMX.Node.Count;i++)
    {
    IPXNode Node = (IPXNode)this.PMX.Node[i];
    for (int j = 0; j < Node.Items.Count; j++)
    {
    if (Node.Items[j].IsBone)
    { if (Node.Items[j].BoneItem.Bone == Bone)
    {
    Node.Items.Remove(Node.Items[j]);
    }
    }
    }
    }


    以上でボーンに関する基本的な操作は網羅してあると思います。

    後はC#の本を買うなりぐぐるなりしてくださいw

    次はモーフに関して記述していきます。


  • 広告
  • PMDEプラグインの作り方 ボーン操作編5

    2013-03-12 21:11

    PMDEプラグインの作り方 ボーン操作編5

    プラグインとはいえ普通にC#なので記述の仕方はいろいろありますが、わかりやすくするために記述方法に制限をかけています。必ずこのやり方でないといけないわけではありませんのでご注意ください。

    前回と同様にこのサンプルプラグインプロジェクトファイル(http://bowlroll.net/up/dl15339)を元に説明しますので必ずDLしてください。
    この中にはボーン操作に必要な機能をあらかじめ入れてあります。説明もそれに沿った形で説明します。また、このプロジェクトファイルの内容を流用してプラグインを作成することは問題ありません。
    以下ボーン操作とそのコードを記述します。前回と同様にサンプルプロジェクトファイルにこぴぺすれば動作すると思います。


    1.多段化してみよう

    例として右ひじを多段化してみます。

    //右ひじを多段化してみる。
    IPXBone BaseBone = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右ひじ", 1)];
    //多段ボーンを一時的に格納する箱
    List<IPXBone> LayerBoneList = new List<IPXBone>();
    //多段数
    int layer = 3;
    for (int i = 0; i < layer; i++)
    {
    //多段用のボーンを元ボーンからコピー
    IPXBone LayerBone = (IPXBone)BaseBone.Clone();
    //かぶらないように名前を変更
    LayerBone.Name = BaseBone.Name + "_" + i.ToString();
    //ボーンを元ボーンの上に追加
    this.UpperInsertBone(LayerBone, BaseBone);
    //一時格納箱に保存
    LayerBoneList.Add(LayerBone);
    }

    //親ボーンの設定
    LayerBoneList[0].Parent = BaseBone.Parent;
    for (int j = 1; j < layer; j++)
    {
    LayerBoneList[j].Parent = LayerBoneList[j - 1];
    }
    BaseBone.Parent = LayerBoneList[layer - 1];


    これで一応右ひじが3段多段化されます。

    しかし、各ボーン単位でこれを記述するのは面倒なので
    次に多段化の部分を関数にして見ます。

    public void CreateLayerBone(IPXBone BaseBone,int layer = 3){
    //多段ボーンを一時的に格納する箱
    List<IPXBone> LayerBoneList = new List<IPXBone>();
    for (int i = 0; i < layer; i++)
    {
    //多段用のボーンを元ボーンからコピー
    IPXBone LayerBone = (IPXBone)BaseBone.Clone();
    //かぶらないように名前を変更
    LayerBone.Name = BaseBone.Name + "_" + i.ToString();
    //ボーンを元ボーンの上に追加
    this.UpperInsertBone(LayerBone, BaseBone);
    //一時格納箱に保存
    LayerBoneList.Add(LayerBone);
    }

    //親ボーンの設定
    LayerBoneList[0].Parent = BaseBone.Parent;
    for (int j = 1; j < layer; j++)
    {
    LayerBoneList[j].Parent = LayerBoneList[j - 1];
    }
    BaseBone.Parent = LayerBoneList[layer - 1];
    }


    このような感じで関数化してプロジェクトに追加すれば
    以下のように記述にできます。
    例)右肩(10段)・右腕(10段)・右ひじ(10段)・右手首(3段)をそれぞれ多段化します。
    IPXBone RightShoulder = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右肩", 1)];
    IPXBone RightArm = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右腕", 1)];
    IPXBone RightElbow = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右ひじ", 1)];
    IPXBone RightWrist = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右手首", 1)];
    this.CreateLayerBone(RightShoulder,10);
    this.CreateLayerBone(RightArm,10);
    this.CreateLayerBone(RightElbow,10);
    this.CreateLayerBone(RightWrist,3);

    このようにして処理単位でまとめておけばあとで便利です。

    次はボーン表示枠について記述していきます。
  • PMDEプラグインの作り方 ボーン操作編4

    2013-03-12 19:24

    PMDEプラグインの作り方 ボーン操作編4

    プラグインとはいえ普通にC#なので記述の仕方はいろいろありますが、わかりやすくするために記述方法に制限をかけています。必ずこのやり方でないといけないわけではありませんのでご注意ください。

    前回と同様にこのサンプルプラグインプロジェクトファイル(http://bowlroll.net/up/dl15339)を元に説明しますので必ずDLしてください。
    この中にはボーン操作に必要な機能をあらかじめ入れてあります。説明もそれに沿った形で説明します。また、このプロジェクトファイルの内容を流用してプラグインを作成することは問題ありません。
    以下ボーン操作とそのコードを記述します。前回と同様にサンプルプロジェクトファイルにこぴぺすれば動作すると思います。


    ・腕IKを作ろう。
    右腕IK(PMX版)を作成します。
    //まず最初に必要な腕ボーンのオブジェクトを取得します

    //必要なボーンの取得
    IPXBone RightShoulder = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右肩", 1)];
    IPXBone RightArm = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右腕", 1)];
    IPXBone RightElbow = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右ひじ", 1)];
    IPXBone RightWrist = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右手首", 1)];

    //次にIKターゲットとなる右手首P
    //IKLinkとなる右腕P・右ひじP用にそれぞれの元ボーンをコピーします。
    IPXBone RightArmP = (IPXBone)RightArm.Clone();
    IPXBone RightElbowP = (IPXBone)RightElbow.Clone();
    IPXBone RightWristP = (IPXBone)RightWrist.Clone();
    //右腕+の設定
    //名前・ボーンの親・ボーンのむきを設定していきます。
    RightArmP.Name = "右腕+";
    RightArmP.Parent = RightShoulder;
    this.SetToBone(RightArmP, RightElbowP);
    //右ひじ+の設定
    //名前・ボーンの親・ボーンのむきを設定していきます。
    RightElbowP.Name = "右ひじ+";

    RightElbowP.Parent = RightArmP;
    this.SetToBone(RightElbowP, RightWristP);
    //右手首+の設定
    //名前・ボーンの親・ボーンのむきを設定していきます。
    RightWristP.Name = "右手首+";

    RightWristP.Parent = RightElbowP;
    this.SetToOffset(RightWristP, new V3(0.0f, 1.0f, 0.0f));

    //右腕IKボーンの設定
    //右腕IKボーンとなるボーンを右手首のコピーとして定義します。
    IPXBone RightArmIK = (IPXBone)RightWrist.Clone();
    //名前の設定をします
    RightArmIK.Name = "右腕IK";
    RightArmIK.Parent = (IPXBone)this.PMX.Bone[0];

    //移動・回転可とします
    //MMDはIKの場合この値に関係なく操作できますが
    //MMMはしっかり設定しないとだめです。
    RightArmIK.IsRotation = true;

    RightArmIK.IsTranslation = true;
    //IKターゲットを設定します。
    this.AddIK(RightArmIK, RightWristP);

    //IKLinkを設定します。
    this.AddIKLink(RightArmIK, RightElbowP);

    this.AddIKLink(RightArmIK, RightArmP);
    this.SetToOffset(RightArmIK, new V3(0.0f, 1.0f, 0.0f));

    //右腕+と右ひじ+の回転を右腕・右ひじに渡すために回転連動の設定 this.SetAppendRotation(RightArm, RightArmP, 1.0f);
    this.SetAppendRotation(RightElbow, RightElbowP, 1.0f);

    //ボーンを右肩の上に追加していく。
    this.UpperInsertBone(RightArmIK, RightShoulder);
    this.UpperInsertBone(RightArmP, RightShoulder);
    this.UpperInsertBone(RightElbowP, RightShoulder);
    this.UpperInsertBone(RightWristP, RightShoulder);

    以上で右腕IKを作成できます。

    ・足IKを作ろう。
    //まず最初に必要な足ボーンのオブジェクトを取得します
    //必要なボーンの取得
    IPXBone LowerBody = (IPXBone)this.PMX.Bone[this.GetBoneIndex("下半身", 1)]; IPXBone RightLeg = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右足", 1)];
    IPXBone RightKnee = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右ひざ", 1)];
    IPXBone RightAnkle = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右足首", 1)];
    IPXBone RightToe = (IPXBone)this.PMX.Bone[this.GetBoneIndex("右つま先", 1)];

    //右足IKボーンの設定
    //右足IKボーンとなるボーンを右足首のコピーとして定義します。
    IPXBone RightLegIK = (IPXBone)RightAnkle.Clone();
    //名前の設定をします。
    RightLegIK.Name = "右足IK";
    RightLegIK.Parent = (IPXBone)this.PMX.Bone[0];
    //移動・回転可とします
    //MMDはIKの場合この値に関係なく操作できますが
    //MMMはしっかり設定しないとだめです。
    RightLegIK.IsRotation = true;
    RightLegIK.IsTranslation = true;
    //IKターゲットを設定します。
    this.AddIK(RightLegIK, RightAnkle);
    //IKLinkを設定します。
    this.AddIKLink(RightLegIK, RightKnee);
    this.AddIKLink(RightLegIK, RightLeg);
    this.SetToOffset(RightLegIK, new V3(0.0f, 0.0f, 1.0f));

    //ボーンを右足の上に追加していく。
    this.UpperInsertBone(RightLegIK, RightLeg);

    以上で足IKの作成手順になります。

    次は多段の記述に行きます。