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

  • PMDEプラグインの作り方 番外編

    2013-03-25 21:19
    PMDEプラグインの作り方 番外編


    私が記述しているコードだけだと何ですので

    参考に出来るようなリンクを紹介します。

    ・@IT 改訂版 C#入門
    http://www.atmarkit.co.jp/ait/subtop/features/da/dt_csharp_abc2_index.html
    ある程度の記述法はここ見るだけで十分です。
    また、独特の記法(LinQ等)は仕事で使うわけでもないので一番学習コストの安い書き方で記述するのが一番です。

    ・@IT 逆コンパイラ「ILSpy」の使い方
    http://www.atmarkit.co.jp/fdotnet/dotnettips/1055ilspy/ilspy.html
    他の人の書かれたC#のコードを見ることが出来るかもしれないツールです。
    PMDEプラグインを作られている方でコードも公開されている方もいらっしゃるのでそれも見るといいと思います。操作の手続き的な部分が参考になります。

    ・SlimDX と C# で学ぶ DirectX

    http://mainori-se.sakura.ne.jp/slimdx/
    PMDE/PMXEで使用されているSlimDXの日本語マニュアルがあります。

    ・@IT Visual Studio 2010の基礎を知る
    http://www.atmarkit.co.jp/ait/articles/1005/26/news096.html
    VisualStudio2010の簡単な説明が載っています。

    画面等を使用しないプラグインのプログラム部分については上記のものでおおよそカバーできます。


    また、当然3Dなので3次元ベクトルのお勉強(UVの部分は2次元ですね)が必要な部分が出てきます。
    さぁ、みんな大好き数学ですw

    ・ラジアン⇔角度
    http://d.hatena.ne.jp/shokai/20080710/1215684866

    ・角度とラジアン
    http://soundweaver.jp/blog/?tag=/%E8%A7%92%E5%BA%A6%E3%81%A8%E3%83%A9%E3%82%B7%E3%82%A2%E3%83%B3

    ・回転行列、拡大縮小行列、平行移動行列
    http://imagingsolution.net/math/rotation-scaling-translation-3d-matrix/

    ・ベクトルの内積・外積
    http://marupeke296.com/COL_Basic_No1_InnerAndOuterProduct.html

    ・ゲーム数学入門
    http://www2.teu.ac.jp/aqua/~earth/GameMath/

    他にもグーグル先生に問い合わせればゲームがらみのサイトでいろいろ説明がされているのがでてきます。ただC++かCで記述されていることがほとんどなのでC#のコードがまるまる書かれていることはないと思ったほうがいいです。

    とりあえず数学と格闘する部分は
    ボーンの場合はローカル軸・回転制限・位置・IKの単位角
    モーフの場合はボーンモーフ
    頂点・面に関してはほぼ全部ですw


  • 広告
  • PMDEプラグインの作り方 モーフ操作編2

    2013-03-19 21:20

    PMDEプラグインの作り方 モーフ操作編2

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

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


    1.システム予約(隠し)モーフにする。
    //まばたきモーフを隠しモーフにしてみます。
    //モーフ名

    string MorphName="まばたき";
    //表示パネル番号
    int panel=0;
    //モーフオブジェクト
    IPXMorph Morph=(IPXMorph)this.PMX.Morph[this.GetMorphIndex(MorphName,1)];
    //表示パネル番号を設定する。
    Morph.panel=panel;

    2.マイナス影響度のモーフを作成する。
    //まばたきモーフをマイナス方向に変化するモーフを作成します。
    //モーフ名

    string MorphName="まばたき";
    //グループモーフ名
    string GroupMorphName = MorphName + "-";
    //モーフIndex
    int i = this.GetMorphIndex(MorphName, 1);
    //表示パネル番号
    int panel = this.PMX.Morph[i].Panel;
    //影響度
    float Effect = -1.0f;
    //グループモーフの追加
    this.AddGroupMorph(GroupMorphName, "", panel, i);
    //グループモーフ内Itemの追加
    this.AddGroupMorphItem(GroupMorphName, MorphName, Effect);

    3.プラス影響度のモーフを作成する。
    //まばたきモーフをプラス方向に変化するモーフを作成します。
    //モーフ名

    string MorphName="まばたき";
    //グループモーフ名
    string GroupMorphName = MorphName + "+";
    //モーフIndex
    int i = this.GetMorphIndex(MorphName, 1);
    //表示パネル番号
    int panel = this.PMX.Morph[i].Panel;
    //影響度
    float Effect = 1.0f;
    //グループモーフの追加
    this.AddGroupMorph(GroupMorphName, "", panel, i);
    //グループモーフ内Itemの追加
    this.AddGroupMorphItem(GroupMorphName, MorphName, Effect);

    4.頂点モーフを左右分割する。
    //まばたきモーフを左右独立して動くモーフに分解します。
    //モーフ名

    string MorphName="まばたき";
    //モーフIndex
    int i = this.GetMorphIndex(MorphName, 1);
    //モーフオブジェクト
    IPXMorph BaseMorph = (IPXMorph)this.PMX.Morph[i];

    //左右分割したモーフの入れ物を定義
    IPXMorph MCloneR = (IPXMorph)this.PMX.Morph[i].Clone();
    IPXMorph MCloneL = (IPXMorph)this.PMX.Morph[i].Clone();

    //右側のモーフの名称の変更と中身のクリア
    MCloneR.Name = MorphName + "R";
    MCloneR.Offsets.Clear();

    //左側のモーフの名称の変更と中身のクリア
    MCloneL.Name = MorphName + "L";
    MCloneL.Offsets.Clear();

    //頂点モーフであることを確認
    if (BaseMorph.Kind == MorphKind.Vertex) {
    //元モーフのオフセット値の検証
    for (int j = 0; j < BaseMorph.Offsets.Count; j++)
    {
    //MorphOffsetItemの生成
    IPXVertexMorphOffset item = (IPXVertexMorphOffset)BaseMorph.Offsets[j];
    if (item.Vertex.Position.X > 0.0f)
    {
    //Xの値が正のものを「L」
    MCloneL.Offsets.Add(item);
    } else {
    //Xの値が0ないし負のものを「R」とする。
    MCloneR.Offsets.Add(item);
    }
    }

    //モーフの追加
    this.UpperInsertMorph(MCloneR, BaseMorph);
    this.UpperInsertMorph(MCloneL, BaseMorph);

    //表情表示枠に追加
    this.AddMorphFrameItem(MCloneR.Name);
    this.AddMorphFrameItem(MCloneL.Name); }

    5.モーフを複製する。
    ①モーフ自体を複製
    //モーフ名
    string MorphName="まばたき";
    //モーフIndex
    int i = this.GetMorphIndex(MorphName,1);
    //モーフオブジェクト
    IPXMorph CloneMorph = (IPXMorph)this.PMX.Morph[i].Clone();
    //名称を変更
    CloneMorph.Name=CloneMorph.Name + "+"; CloneMorph.NameE=CloneMorph.NameE + "+";
    //モーフの追加
    this.AddMorph(CloneMorph.Name,CloneMorph.NameE,CloneMorph.kind,CloneMorph.Panel,i);

    ②グループモーフとして複製
    //モーフ名
    string MorphName="まばたき";
    //グループモーフ名
    string GroupMorphName = "+" + MorphName;
    //モーフIndex
    int i = this.GetMorphIndex(MorphName,1);
    //表示パネル番号
    int panel = this.PMX.Morph[i].Panel;
    //グループモーフの追加
    this.AddGroupMorph(GroupMorphName, "", panel, i);
    //グループモーフ内Itemの追加
    this.AddGroupMorphItem(GroupMorphName, MorphName, 1.0f);

    闇鍋プラグインに入れてあるモーフ操作部分から抜粋しました。

    次はプラグインの中に何が書いてあるかある程度見ることが出来るツールを紹介します。

  • PMDEプラグインの作り方 モーフ操作編1

    2013-03-17 02:521
    PMDEプラグインの作り方 モーフ操作編1

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

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


    1.モーフIndexの取得
    //モーフ名
    string MorphName ="まばたき";
    //モーフIndex
    int Index=-1;
    //モーフを順番に検索します。
    for (int i = 0; i < this.PMX.Morph.Count; i++)
    {
    //モーフの名前が同じものがあればIndexにiを代入します。
    if (this.PMX.Morph[i].Name == MorphName)
    {
    Index =i;
    }
    }

    2.モーフ表示枠内Indexを取得する。
    //モーフ名
    string MorphName="まばたき";
    //モーフIndex
    int Index=-1;
    //モーフオブジェクトの取得
    IPXMorph Morph = (IPXMorph)this.PMX.Morph[this.GetMorphIndex(MorphName, 1)];
    //表情表示枠の取得
    IPXNode ExpressionNode = (IPXNode)this.PMX.ExpressionNode;
    //表情表示枠の中を順番に検索
    for (int i = 0; i < ExpressionNode.Items.Count; i++)
    {
    if (ExpressionNode.Items[i].IsMorph)
    {
    //一致するものがあればIndexにiを代入
    if (ExpressionNode.Items[i].MorphItem.Morph == Morph)
    {
    Index=i;
    }
    }
    }

    3.モーフを追加する。
    //kindはモーフの種類。
    //モーフの挿入場所を設定。
    int position =0;
    //モーフ表示パネルの設定
    // 0:システム予約 1:眉(左下) 2:目(左上) 3:口(右上) 4:その他(右下)
    int panel=1;
    //モーフオブジェクトを生成する。
    IPXMorph item = PEStaticBuilder.Pmx.Morph();
    //オブジェクトの設定をする。
    item.Name = MorphName;
    item.NameE = MorphNameE;
    item.Kind = kind;
    item.Panel = panel;
    //モーフを追加する。
    this.PMX.Morph.Insert(position, item);

    4.モーフを表情表示枠に追加する。
    //モーフIndexを取得
    int i = GetMorphIndex(MorphName, 1);
    //表示枠に追加するオブジェクトを作成
    IPXNodeItem item = PEStaticBuilder.Pmx.MorphNodeItem(this.PMX.Morph[i]);
    //表情表示枠にモーフを追加する。
    this.PMX.ExpressionNode.Items.Add(item);

    5.ボーンモーフにボーンを追加する。
    //モーフの取得
    IPXMorph morph = (IPXMorph)this.PMX.Morph[this.GetMorphIndex("お辞儀")];
    //ボーンの取得
    IPXBone Bone=(IPXBone)this.PMX.Bone[this.GetBoneIndex("頭")];
    //ボーンモーフであることを確認

    if (morph.Kind == MorphKind.Bone)
    {
    //ボーンモーフアイテムの生成
    IPXBoneMorphOffset item = PEStaticBuilder.Pmx.BoneMorphOffset();
    //ボーンモーフアイテムの設定
    item.Bone = Bone;
    item.Rotation = rotation;
    item.Translation = translation;
    //ボーンモーフアイテムの追加
    morph.Offsets.Add(item);
    }

    6.グループモーフの追加
    //モーフの取得
    IPXMorph morph = (IPXMorph)this.PMX.Morph[this.GetMorphIndex("目閉じる")];
    //追加するモーフの取得
    IPXMorph addmorph = (IPXMorph)this.PMX.Morph[this.GetMorphIndex("まばたき")];
    //影響度
    float ratio=1.0f;
    //グループモーフであることを確認

    if (morph.Kind == MorphKind.Group)
    {
    //グループモーフアイテムの生成
    IPXGroupMorphOffset item = PEStaticBuilder.Pmx.GroupMorphOffset();
    item.Morph = addmorph;
    item.Ratio = ratio;
    morph.Offsets.Add(item);
    }

    頂点モーフ・材質モーフも同様の操作です。

    モーフの基本的な操作は以上です。

    次に応用的な操作のサンプルを記述します。