コード例 #1
0
ファイル: CorrespondTable.cs プロジェクト: superowner/tso2pmx
        void ReadBoneStructure(string path)
        {
            using (StreamReader sr = new StreamReader(path, encoding))
            {
                string line = null;

                while ((line = sr.ReadLine()) != null)
                {
                    string[] row = line.Split(',');

                    string bone_name   = row[0].Trim();
                    string bone_kind   = row[1].Trim();
                    string parent_name = row[2].Trim();
                    string tail_name   = row[3].Trim();
                    string target_name = row[4].Trim();
                    string disp_name   = row[5].Trim();

                    PMD_Bone pmd_b = new PMD_Bone();

                    pmd_b.name       = bone_name;
                    pmd_b.Kind       = int.Parse(bone_kind);
                    pmd_b.ParentName = (parent_name != "") ? parent_name : null;
                    pmd_b.TailName   = (tail_name != "") ? tail_name : null;
                    pmd_b.TargetName = (target_name != "") ? target_name : null;

                    // すでにpmd_b.nameが存在するなら上書き
                    boneStructure[pmd_b.name] = pmd_b;

                    if (disp_name != "")
                    {
                        AddBoneNameInDisp(bone_name, disp_name);
                    }
                }
            }
        }
コード例 #2
0
ファイル: PmxFile.cs プロジェクト: superowner/tso2pmx
        // ボーン名をIDに置き換える
        public void SetBoneIDFromName(PmxFile pmd)
        {
            parent_node_id = pmd.GetBoneIDByName(ParentName);
            tail_node_id   = pmd.GetBoneIDByName(TailName);
            target_node_id = pmd.GetBoneIDByName(TargetName);

            if (parent_node_id != -1)
            {
                // 親が捩りボーンなら軸固定を設定する
                PMD_Bone parent = pmd.nodes[parent_node_id];
                if (parent.flags_hi == 0x04)
                {
                    parent.axis = Vector3.Normalize(position - parent.position);
                }
            }
        }
コード例 #3
0
ファイル: TransTso2Pmd.cs プロジェクト: superowner/tso2pmx
        /// 親子関係を元に並び替える
        static void SortNodes(List <PMD_Bone> nodes)
        {
            for (int i = 0; i < nodes.Count; i++)
            {
                PMD_Bone node = nodes[i];
                //親より前に居る子を見つける
                for (int j = 0; j < i; j++)
                {
                    if (nodes[j].ParentName == node.name)
                    {
                        //親を削除
                        nodes.RemoveAt(i);
                        //親を子の直前に挿入
                        nodes.Insert(j, node);

                        break;
                    }
                }
            }
        }
コード例 #4
0
        // -----------------------------------------------------
        // FigureデータよりPmdFileデータを作成
        // -----------------------------------------------------
        public string Figure2PmdFileDataWithHumanBone()
        {
            CorrespondTable cor_table = null;
            int             mod_type  = 0;

            if (fig.Tmo.nodes.Length == 227)
            {
                corTable_list.SetManFlag = false;
                cor_table = corTable_list.GetCorrespondTable();
                mod_type  = 0;
            }
            else if (fig.Tmo.nodes.Length == 75)
            {
                corTable_list.SetManFlag = true;
                cor_table = corTable_list.GetCorrespondTable();
                mod_type  = 1;
            }
            else
            {
                return("未対応のボーン構造です。\n人型以外を変換する場合は、\n出力ボーンに”1ボーン”を指定してください。");
            }

            // -----------------------------------------------------
            // 予め、情報をコピーするmeshを選定し、並び替えておく
            // -----------------------------------------------------
            SelectMeshes();

            // -----------------------------------------------------
            // 頂点
            // -----------------------------------------------------
            MakePMDVertices(cor_table, mod_type);

            // 頂点数が上限を超えてないかチェックし、超えていたらエラーを出して終了
            if (pmd.number_of_vertex > 65535)
            {
                return("頂点数(" + pmd.number_of_vertex.ToString() + ")が上限(65535)を超えています。");
            }

            // -----------------------------------------------------
            // 表情
            // -----------------------------------------------------
            if (mod_type == 0)
            {
                InitializePMDFaces();
                MakePMDBaseFace();
                MakePMDFaces();
            }
            else if (mod_type == 1)
            {
                InitializePMDFaces();
                MakePMDBaseFace();
                pmd.number_of_face = 0;
            }

            // -----------------------------------------------------
            // 表情枠
            // -----------------------------------------------------
            if (mod_type == 0)
            {
                pmd.skin_disp_count = pmd.number_of_face - 1; // 表情枠に表示する表情数
                pmd.skin_index      = new int[pmd.skin_disp_count];
                for (int i = 0; i < pmd.skin_disp_count; i++)
                {
                    pmd.skin_index[i] = i + 1; // 表情番号
                }
            }
            else if (mod_type == 1)
            {
                pmd.skin_disp_count = 0; // 表情枠に表示する表情数
            }

            // -----------------------------------------------------
            // ボーン情報
            // -----------------------------------------------------
            List <PMD_Bone> bone_list = new List <PMD_Bone>();

            foreach (KeyValuePair <string, PMD_Bone> bone_kvp in cor_table.boneStructure)
            {
                PMD_Bone pmd_b = new PMD_Bone();
                PMD_Bone bone  = bone_kvp.Value;

                pmd_b.szName       = bone.szName;
                pmd_b.cbKind       = bone.cbKind; // ボーンの種類 0:回転 1:回転と移動 2:IK 3:不明 4:IK影響下 5:回転影響下 6:IK接続先 7:非表示 8:捻り 9:回転運動
                pmd_b.ParentName   = bone.ParentName;
                pmd_b.ChildName    = bone.ChildName;
                pmd_b.IKTargetName = bone.IKTargetName;

                string bone_name = null;
                cor_table.bonePosition.TryGetValue(pmd_b.szName, out bone_name);
                if (bone_name != null)
                {
                    pmd_b.vec3Position
                        = Trans.CopyMat2Pos(fig.Tmo.FindNodeByName(bone_name).combined_matrix); // モデル原点からの位置
                }

                bone_list.Add(pmd_b);
            }

            // -----------------------------------------------------
            // 親と子の前後関係を並び替える
            for (int i = 0; i < bone_list.Count; i++)
            {
                for (int j = 0; j < bone_list.Count; j++)
                {
                    if (bone_list[i].szName == bone_list[j].ParentName)
                    {
                        if (i > j)
                        {
                            bone_list.Insert(j, bone_list[i]);
                            bone_list.RemoveAt(i + 1);
                        }
                    }
                }
            }

            // -----------------------------------------------------
            // リストを配列に代入し直す
            pmd.number_of_bone = bone_list.Count;
            pmd.pmd_bone       = (PMD_Bone[])bone_list.ToArray();

            // -----------------------------------------------------
            // センターボーンの位置調整
            pmd.getBoneByName("センター").vec3Position
                = new MmdVector3(
                      0.0f,
                      pmd.getBoneByName("下半身").vec3Position.y * 0.65f,
                      0.0f);
            pmd.getBoneByName("センター先").vec3Position
                = new MmdVector3(
                      0.0f,
                      0.0f,
                      0.0f);

            // -----------------------------------------------------
            // 両目ボーンの位置調整
            if (mod_type == 0)
            {
                pmd.getBoneByName("両目").vec3Position
                    = new MmdVector3(
                          0.0f,
                          pmd.getBoneByName("左目").vec3Position.y + pmd.getBoneByName("左目").vec3Position.x * 4.0f,
                          pmd.getBoneByName("左目").vec3Position.z - pmd.getBoneByName("左目").vec3Position.x * 2.0f);
                pmd.getBoneByName("両目先").vec3Position
                    = new MmdVector3(
                          pmd.getBoneByName("両目").vec3Position.x,
                          pmd.getBoneByName("両目").vec3Position.y,
                          pmd.getBoneByName("両目").vec3Position.z - 1.0f);
            }

            // -----------------------------------------------------
            // IK先ボーンの位置調整
            pmd.getBoneByName("左足IK先").vec3Position
                = new MmdVector3(
                      pmd.getBoneByName("左足IK").vec3Position.x,
                      pmd.getBoneByName("左足IK").vec3Position.y,
                      pmd.getBoneByName("左足IK").vec3Position.z + 1.7f);
            pmd.getBoneByName("右足IK先").vec3Position
                = new MmdVector3(
                      pmd.getBoneByName("右足IK").vec3Position.x,
                      pmd.getBoneByName("右足IK").vec3Position.y,
                      pmd.getBoneByName("右足IK").vec3Position.z + 1.7f);

            pmd.getBoneByName("左つま先").vec3Position.y   = 0.0f;
            pmd.getBoneByName("左つま先IK").vec3Position.y = 0.0f;
            pmd.getBoneByName("左つま先IK先").vec3Position
                = new MmdVector3(
                      pmd.getBoneByName("左つま先IK").vec3Position.x,
                      pmd.getBoneByName("左つま先IK").vec3Position.y - 1.0f,
                      pmd.getBoneByName("左つま先IK").vec3Position.z);

            pmd.getBoneByName("右つま先").vec3Position.y   = 0.0f;
            pmd.getBoneByName("右つま先IK").vec3Position.y = 0.0f;
            pmd.getBoneByName("右つま先IK先").vec3Position
                = new MmdVector3(
                      pmd.getBoneByName("右つま先IK").vec3Position.x,
                      pmd.getBoneByName("右つま先IK").vec3Position.y - 1.0f,
                      pmd.getBoneByName("右つま先IK").vec3Position.z);

            // -----------------------------------------------------
            // IK配列
            // -----------------------------------------------------
            pmd.number_of_ik = cor_table.IKBone.Count;
            pmd.pmd_ik       = (PMD_IK[])cor_table.IKBone.ToArray();

            // -----------------------------------------------------
            // ボーン枠用枠名リスト
            // -----------------------------------------------------
            pmd.bone_disp_name_count = cor_table.dispBoneGroup.Count;        // ボーン枠用の枠名数
            pmd.disp_name            = new string[pmd.bone_disp_name_count]; // 枠名(50Bytes/枠)

            for (int i = 0; i < cor_table.dispBoneGroup.Count; i++)
            {
                pmd.disp_name[i] = cor_table.dispBoneGroup[i].group_name + Convert.ToChar(Convert.ToInt16("0A", 16));
            }
            //PMDEditorを使う場合は、枠名を0x0A00で終わらせる必要があります(0x00のみだと表示されません)。

            // -----------------------------------------------------
            // ボーン枠用表示リスト
            // -----------------------------------------------------
            // 枠に表示するボーン数
            pmd.bone_disp_count = 0;
            for (int i = 0; i < cor_table.dispBoneGroup.Count; i++)
            {
                pmd.bone_disp_count += cor_table.dispBoneGroup[i].bone_name_list.Count;
            }

            // 枠用ボーンデータ (3Bytes/bone)
            pmd.bone_disp = new PMD_BoneDisp[pmd.bone_disp_count];

            int n      = 0; // 通し番号
            int n_disp = 1;

            foreach (DispBoneGroup dbg in cor_table.dispBoneGroup)
            {
                foreach (string name in dbg.bone_name_list)
                {
                    pmd.bone_disp[n]           = new PMD_BoneDisp();
                    pmd.bone_disp[n].bone_name = name;                 // 枠用ボーン名
                    pmd.bone_disp[n++].bone_disp_frame_index = n_disp; // 表示枠番号
                }
                n_disp++;
            }

            // -----------------------------------------------------
            // 英名対応(0:英名対応なし, 1:英名対応あり)
            // -----------------------------------------------------
            pmd.english_name_compatibility = 0;

            // -----------------------------------------------------
            // 剛体&ジョイント
            // -----------------------------------------------------
            // -----------------------------------------------------
            // 物理オブジェクトを生成
            physOb_list = new T2PPhysObjectList(bone_list);

            // -----------------------------------------------------
            // テンプレートを適用
            template_list.PhysObExecute(ref physOb_list);

            // -----------------------------------------------------
            // 剛体&ジョイントを配列に代入し直す
            pmd.rigidbody_count = physOb_list.body_list.Count;
            pmd.rigidbody       = (PMD_RigidBody[])physOb_list.body_list.ToArray();

            pmd.joint_count = physOb_list.joint_list.Count;
            pmd.joint       = (PMD_Joint[])physOb_list.joint_list.ToArray();

            // -----------------------------------------------------
            // 終了
            return("");
        }
コード例 #5
0
ファイル: TransTso2Pmd.cs プロジェクト: superowner/tso2pmx
        /// Figureを元にPmdFileを更新します。
        /// ボーンは人型です。
        public void UpdatePmdFromFigureWithHumanBone()
        {
            int mod_type = 0;

            if (fig.Tmo.nodes.Length == 227)
            {
                mod_type = 0;
            }
            else if (fig.Tmo.nodes.Length == 75)
            {
                mod_type = 1;
            }
            else
            {
                throw new FormatException("未対応のボーン構造です。\n人型以外を変換する場合は、\n出力ボーンに\"1ボーン\"を指定してください。");
            }

            CorrespondTable cortable;

            if (mod_type == 0)
            {
                cortable = cortable_list.GetCorrespondTable();
            }
            else
            {
                cortable_list.BoneKind = CorrespondTableListBoneKind.man;
                cortable = cortable_list.GetCorrespondTable();
            }

            // -----------------------------------------------------
            // ボーン情報
            // -----------------------------------------------------
            List <PMD_Bone> nodes = new List <PMD_Bone>();

            foreach (KeyValuePair <string, PMD_Bone> bone_kvp in cortable.boneStructure)
            {
                PMD_Bone bone  = bone_kvp.Value;
                PMD_Bone pmd_b = new PMD_Bone();

                pmd_b.name       = bone.name;
                pmd_b.name_en    = bone.name_en;
                pmd_b.Kind       = bone.Kind;
                pmd_b.ParentName = bone.ParentName;
                pmd_b.TailName   = bone.TailName;
                pmd_b.TargetName = bone.TargetName;

                string bone_name = null;
                cortable.bonePositions.TryGetValue(pmd_b.name, out bone_name);
                if (bone_name != null)
                {
                    pmd_b.position
                        = Trans.CopyMat2Pos(fig.Tmo.FindNodeByName(bone_name).combined_matrix); // モデル原点からの位置
                }

                nodes.Add(pmd_b);
            }

            SortNodes(nodes);

            // -----------------------------------------------------
            // リストを配列に代入し直す
            pmd.nodes = nodes.ToArray();

            UpdateRootBonePosition();

            if (mod_type == 0)
            {
                UpdateEyesBonePosition();
            }

            UpdateIKTailBonePosition();

            // -----------------------------------------------------
            // 予め、情報をコピーするmeshを選定し、並び替えておく
            // -----------------------------------------------------
            SelectMeshes();

            // -----------------------------------------------------
            // 頂点
            // -----------------------------------------------------
            MakePMDVertices(cortable, mod_type);

            // -----------------------------------------------------
            // 表情
            // -----------------------------------------------------
            if (mod_type == 0)
            {
                InitializePMDFaces();
                MakePMDFaces();
            }
            else
            {
                InitializePMDFaces();
                pmd.skins = new PMD_Skin[0];
            }

            // -----------------------------------------------------
            // IK配列
            // -----------------------------------------------------
            pmd.iks = cortable.iks.ToArray();

            // -----------------------------------------------------
            // 表示枠
            // -----------------------------------------------------
            pmd.disp_groups = cortable.boneDispGroups;

            if (mod_type == 0)
            {
                PMD_DispGroup disp_group = pmd.disp_groups[1];//表情枠

                for (int i = 0; i < pmd.skins.Length; i++)
                {
                    PMD_SkinDisp skin_disp = new PMD_SkinDisp();
                    skin_disp.skin_id = (sbyte)i;
                    disp_group.disps.Add(skin_disp);
                }
            }

            if (mod_type == 0)
            {
                T2PPhysObjectList physOb_list = new T2PPhysObjectList(nodes);

                template_list.PhysObExecute(ref physOb_list);

                pmd.bodies = physOb_list.bodies.ToArray();
                pmd.joints = physOb_list.joints.ToArray();
            }
            else
            {
                pmd.bodies = new PMD_RBody[0];
                pmd.joints = new PMD_Joint[0];
            }
        }