Beispiel #1
0
        PmxHeader ReadPmxHeader(BinaryReader br)
        {
            var header = new PmxHeader();

            // マジック読み込み
            header.Magic = new string(br.ReadChars(4));
            if (header.Magic != "PMX " && header.Magic != "Pmx ")
            {
                return(null);
            }

            // バージョン読み込み
            header.Version = br.ReadSingle();

            // 各種バイト情報読み込み
            var size = br.ReadByte();

            for (var i = 0; i < size; i++)
            {
                var data = br.ReadByte();
                if (i == 0)
                {
                    header.Encoding = data;
                }
                else if (i == 1)
                {
                    header.AddUVCound = data;
                }
                else if (i == 2)
                {
                    header.VertexIndexSize = data;
                }
                else if (i == 3)
                {
                    header.TextureIndexSize = data;
                }
                else if (i == 4)
                {
                    header.MaterialIndexSize = data;
                }
                else if (i == 5)
                {
                    header.BoneIndexSize = data;
                }
                else if (i == 6)
                {
                    header.MorphIndexSize = data;
                }
                else if (i == 7)
                {
                    header.RigidIndexSize = data;
                }
            }

            return(header);
        }
Beispiel #2
0
        PmxMaterialList ReadPmxMaterialList(BinaryReader br, PmxHeader header)
        {
            var encode = header.Encoding == 0 ? Encoding.Unicode : Encoding.UTF8;

            var matList = new PmxMaterialList();

            // マテリアルの数を読み込み
            matList.MaterialNum = br.ReadInt32();

            matList.Materials = new PmxMaterial[matList.MaterialNum];
            for (int i = 0; i < matList.MaterialNum; i++)
            {
                PmxMaterial mat = new PmxMaterial();

                mat.Name    = br.ReadString(encode);                                    // 材質名
                mat.NameEng = br.ReadString(encode);                                    // 材質英名

                mat.Diffuse       = br.ReadVector4();                                   // Diffuse (R,G,B,A)
                mat.Specular      = br.ReadVector3();                                   // Specular (R,G,B)
                mat.SpecularPower = br.ReadSingle();                                    // Specular係数
                mat.Ambient       = br.ReadVector3();                                   // Ambient (R,G,B)

                var bitFlag = br.ReadByte();
                mat.BothFace          = (bitFlag & 0x01) != 0;                         // 両面描画
                mat.GroundShadow      = (bitFlag & 0x02) != 0;                         // 地面影
                mat.DrawSelfShadowMap = (bitFlag & 0x04) != 0;                         // セルフシャドウマップへの描画
                mat.SelfShadow        = (bitFlag & 0x08) != 0;                         // セルフシャドウの描画
                mat.DrawEdge          = (bitFlag & 0x10) != 0;                         // エッジ描画

                mat.EdgeColor = br.ReadVector4();                                      // エッジ色 (R,G,B,A)
                mat.EdgeSize  = br.ReadSingle();                                       // エッジサイズ

                mat.AlbedoMapIndex = br.ReadFromIndexSize(header.TextureIndexSize);    // 通常テクスチャ
                mat.SphereMapIndex = br.ReadFromIndexSize(header.TextureIndexSize);    // スフィアテクスチャ
                mat.SphereMode     = br.ReadByte();                                    // スフィアモード 0:無効 1:乗算(sph) 2:加算(spa) 3:サブテクスチャ(追加UV1のx,yをUV参照して通常テクスチャ描画を行う)

                mat.SharedToon = br.ReadByte() == 1;                                   // 共有Toonフラグ
                if (mat.SharedToon)
                {
                    mat.ToonMapIndex = br.ReadFromIndexSize(header.TextureIndexSize);
                }
                else
                {
                    mat.ToonMapIndex = br.ReadByte();
                }

                mat.Memo        = br.ReadString(encode);                                // メモ : 自由欄/スクリプト記述/エフェクトへのパラメータ配置など
                mat.FaceVertNum = br.ReadInt32();                                       // 材質に対応する面(頂点)数 (必ず3の倍数になる)

                matList.Materials[i] = mat;
            }

            return(matList);
        }
Beispiel #3
0
        PmxTextureList ReadPmxTextureList(BinaryReader br, PmxHeader header)
        {
            var encode = header.Encoding == 0 ? Encoding.Unicode : Encoding.UTF8;

            var textureList = new PmxTextureList();

            // テクスチャ数を読み込み
            textureList.TextureNum = br.ReadInt32();

            // 面の読み込み
            textureList.Textures = new string[textureList.TextureNum];
            for (int i = 0; i < textureList.TextureNum; i++)
            {
                textureList.Textures[i] = br.ReadString(encode);
            }

            return(textureList);
        }
Beispiel #4
0
        PmxFaceList ReadPmxFaceList(BinaryReader br, PmxHeader header)
        {
            var faceList = new PmxFaceList();

            // 面数を読み込み
            faceList.FaceVertNum = br.ReadInt32();
            if (faceList.FaceVertNum % 3 != 0)
            {
                return(null);
            }

            // 面の読み込み
            faceList.Faces = new int[faceList.FaceVertNum];
            for (int i = 0; i < faceList.FaceVertNum; i++)
            {
                faceList.Faces[i] = br.ReadFromVertexIndexSize(header.VertexIndexSize);
            }

            return(faceList);
        }
Beispiel #5
0
        PmxModelInfo ReadPmxModelInfo(BinaryReader br, PmxHeader header)
        {
            var encode = header.Encoding == 0 ? Encoding.Unicode : Encoding.UTF8;

            var info = new PmxModelInfo();

            // モデル名
            info.ModelName = br.ReadString(encode);

            // モデル英名
            info.ModelNameEng = br.ReadString(encode);

            // コメント
            info.Comment = br.ReadString(encode);

            // 英コメント
            info.CommentEng = br.ReadString(encode);

            return(info);
        }
Beispiel #6
0
        PmxMorphList ReadPmxMorphList(BinaryReader br, PmxHeader header)
        {
            var encode = header.Encoding == 0 ? Encoding.Unicode : Encoding.UTF8;

            var morphList = new PmxMorphList();

            morphList.MorphNum = br.ReadInt32();

            var vertList  = new List <PmxMorph <PmxMorphVertex> >();
            var uvList    = new List <PmxMorph <PmxMorphUV> >();
            var uv1List   = new List <PmxMorph <PmxMorphUV> >();
            var uv2List   = new List <PmxMorph <PmxMorphUV> >();
            var uv3List   = new List <PmxMorph <PmxMorphUV> >();
            var uv4List   = new List <PmxMorph <PmxMorphUV> >();
            var boneList  = new List <PmxMorph <PmxMorphBone> >();
            var matList   = new List <PmxMorph <PmxMorphMaterial> >();
            var groupList = new List <PmxMorph <PmxMorphGroup> >();

            for (var i = 0; i < morphList.MorphNum; i++)
            {
                var name    = br.ReadString(encode);        // モーフ名
                var nameEng = br.ReadString(encode);        // モーフ英名

                var opePanel = br.ReadByte();
                var type     = br.ReadByte();
                var num      = br.ReadInt32();

                if (type == 0) // グループモーフ
                {
                    var g = new PmxMorph <PmxMorphGroup>()
                    {
                        Name         = name,
                        NameEng      = nameEng,
                        OperatePanel = opePanel,
                        MorphType    = type,
                    };
                    g.Data = new PmxMorphGroup[num];
                    for (var j = 0; j < num; j++)
                    {
                        g.Data[j]       = new PmxMorphGroup();
                        g.Data[j].Index = br.ReadFromVertexIndexSize(header.MorphIndexSize);
                        g.Data[j].Rate  = br.ReadSingle();
                    }
                    groupList.Add(g);
                }
                else if (type == 1) // 頂点モーフ
                {
                    var vertex = new PmxMorph <PmxMorphVertex>()
                    {
                        Name         = name,
                        NameEng      = nameEng,
                        OperatePanel = opePanel,
                        MorphType    = type,
                    };
                    vertex.Data = new PmxMorphVertex[num];
                    for (var j = 0; j < num; j++)
                    {
                        vertex.Data[j]          = new PmxMorphVertex();
                        vertex.Data[j].Index    = br.ReadFromVertexIndexSize(header.VertexIndexSize);
                        vertex.Data[j].Position = br.ReadVector3();
                    }
                    vertList.Add(vertex);
                }
                else if (type == 2) // ボーンモーフ
                {
                    var bone = new PmxMorph <PmxMorphBone>()
                    {
                        Name         = name,
                        NameEng      = nameEng,
                        OperatePanel = opePanel,
                        MorphType    = type,
                    };
                    bone.Data = new PmxMorphBone[num];
                    for (var j = 0; j < num; j++)
                    {
                        bone.Data[j]             = new PmxMorphBone();
                        bone.Data[j].Index       = br.ReadFromVertexIndexSize(header.BoneIndexSize);
                        bone.Data[j].Translation = br.ReadVector3();
                        bone.Data[j].Quaternion  = br.ReadVector4();
                    }
                    boneList.Add(bone);
                }
                else if (type == 3 || type == 4 || type == 5 || type == 6 || type == 7) // UVモーフ
                {
                    var uv = new PmxMorph <PmxMorphUV>()
                    {
                        Name         = name,
                        NameEng      = nameEng,
                        OperatePanel = opePanel,
                        MorphType    = type,
                    };
                    uv.Data = new PmxMorphUV[num];
                    for (var j = 0; j < num; j++)
                    {
                        uv.Data[j]       = new PmxMorphUV();
                        uv.Data[j].Index = br.ReadFromVertexIndexSize(header.VertexIndexSize);
                        uv.Data[j].UV    = br.ReadVector4();
                    }
                    if (type == 3)
                    {
                        uvList.Add(uv);
                    }
                    else if (type == 4)
                    {
                        uv1List.Add(uv);
                    }
                    else if (type == 5)
                    {
                        uv2List.Add(uv);
                    }
                    else if (type == 6)
                    {
                        uv3List.Add(uv);
                    }
                    else if (type == 7)
                    {
                        uv4List.Add(uv);
                    }
                }
                else if (type == 8) // 材質モーフ
                {
                    var mat = new PmxMorph <PmxMorphMaterial>()
                    {
                        Name         = name,
                        NameEng      = nameEng,
                        OperatePanel = opePanel,
                        MorphType    = type,
                    };
                    mat.Data = new PmxMorphMaterial[num];
                    for (var j = 0; j < num; j++)
                    {
                        mat.Data[j]                = new PmxMorphMaterial();
                        mat.Data[j].Index          = br.ReadFromVertexIndexSize(header.MaterialIndexSize);
                        mat.Data[j].OperationType  = br.ReadByte();
                        mat.Data[j].Diffuse        = br.ReadVector4();
                        mat.Data[j].Specular       = br.ReadVector3();
                        mat.Data[j].SpecularPower  = br.ReadSingle();
                        mat.Data[j].Ambient        = br.ReadVector3();
                        mat.Data[j].EdgeColor      = br.ReadVector4();
                        mat.Data[j].EdgeSize       = br.ReadSingle();
                        mat.Data[j].TexCoeff       = br.ReadVector4();
                        mat.Data[j].SphereTexCoeff = br.ReadVector4();
                        mat.Data[j].ToonTexCoeff   = br.ReadVector4();
                    }
                    matList.Add(mat);
                }
            }

            if (vertList.Count > 0)
            {
                morphList.VertexList = vertList.ToArray();
            }
            if (uvList.Count > 0)
            {
                morphList.UVList = uvList.ToArray();
            }
            if (uv1List.Count > 0)
            {
                morphList.UV1List = uv1List.ToArray();
            }
            if (uv2List.Count > 0)
            {
                morphList.UV2List = uv2List.ToArray();
            }
            if (uv3List.Count > 0)
            {
                morphList.UV3List = uv3List.ToArray();
            }
            if (uv4List.Count > 0)
            {
                morphList.UV4List = uv4List.ToArray();
            }
            if (boneList.Count > 0)
            {
                morphList.BoneList = boneList.ToArray();
            }
            if (matList.Count > 0)
            {
                morphList.MaterialList = matList.ToArray();
            }
            if (groupList.Count > 0)
            {
                morphList.GroupList = groupList.ToArray();
            }

            return(morphList);
        }
Beispiel #7
0
        PmxBoneList ReadPmxBoneList(BinaryReader br, PmxHeader header)
        {
            var encode = header.Encoding == 0 ? Encoding.Unicode : Encoding.UTF8;

            var boneList = new PmxBoneList();

            // ボーンの数を読み込み
            boneList.BoneNum = br.ReadInt32();

            boneList.Bones = new PmxBone[boneList.BoneNum];
            for (var i = 0; i < boneList.BoneNum; i++)
            {
                PmxBone bone = new PmxBone();

                bone.BoneName    = br.ReadString(encode);                          // ボーン名
                bone.BoneNameEng = br.ReadString(encode);                          // ボーン英名

                bone.Position        = br.ReadVector3();                           // 位置
                bone.ParentBoneIndex = br.ReadFromIndexSize(header.BoneIndexSize); // 親ボーンのボーンIndex
                bone.TransformLayer  = br.ReadInt32();                             // 変形階層

                var flag = br.ReadUInt16();
                bone.ConnectionVisible = (flag & 0x0001) != 0;  // 接続先(PMD子ボーン指定)表示方法
                bone.EnableRotate      = (flag & 0x0002) != 0;
                bone.EnableTranslate   = (flag & 0x0004) != 0;
                bone.Visible           = (flag & 0x0008) != 0;
                bone.Operatable        = (flag & 0x0010) != 0;
                bone.IsIK           = (flag & 0x0020) != 0;
                bone.GrantLocal     = (flag & 0x0080) != 0;
                bone.GrantRotate    = (flag & 0x0100) != 0;
                bone.GrantTranslate = (flag & 0x0200) != 0;
                bone.FixedAxis      = (flag & 0x0400) != 0;
                bone.LocalAxis      = (flag & 0x0800) != 0;
                bone.AfterPhysics   = (flag & 0x1000) != 0;
                bone.OuterParent    = (flag & 0x2000) != 0;

                if (!bone.ConnectionVisible)
                {
                    bone.Offset = br.ReadVector3();
                }
                else
                {
                    bone.BoneIndex = br.ReadFromIndexSize(header.BoneIndexSize);
                }

                if (bone.GrantRotate || bone.GrantTranslate)
                {
                    bone.GrantParentBoneIndex  = br.ReadFromIndexSize(header.BoneIndexSize);
                    bone.GrantParentBoneWeight = br.ReadSingle();
                }

                if (bone.FixedAxis)
                {
                    bone.Axis = br.ReadVector3();
                }

                if (bone.LocalAxis)
                {
                    bone.AxisX = br.ReadVector3();
                    bone.AxisZ = br.ReadVector3();
                }

                if (bone.OuterParent)
                {
                    bone.Key = br.ReadInt32();
                }

                if (bone.IsIK)
                {
                    bone.IKBoneIndex      = br.ReadFromIndexSize(header.BoneIndexSize);
                    bone.IKLoop           = br.ReadInt32();
                    bone.IKLoopLimitAngle = br.ReadSingle();
                    bone.IKLinkNum        = br.ReadInt32();
                    bone.IKLinks          = new PmxIKLink[bone.IKLinkNum];
                    for (var ik = 0; ik < bone.IKLinkNum; ik++)
                    {
                        var link = new PmxIKLink();
                        link.BoneIndex  = br.ReadFromIndexSize(header.BoneIndexSize);
                        link.LimitAngle = br.ReadByte() == 1;
                        if (link.LimitAngle)
                        {
                            link.LowerLimitAngle = br.ReadVector3();
                            link.UpperLimitAngle = br.ReadVector3();
                        }
                        bone.IKLinks[ik] = link;
                    }
                }

                boneList.Bones[i] = bone;
            }

            return(boneList);
        }
Beispiel #8
0
        PmxVertexList ReadPmxVertexList(BinaryReader br, PmxHeader header)
        {
            var vertList = new PmxVertexList();

            // 頂点数読み込み
            vertList.VertexNum = br.ReadInt32();

            // 頂点データの読み込み
            vertList.Vertices = new PmxVertex[vertList.VertexNum];
            for (int i = 0; i < vertList.VertexNum; i++)
            {
                var vertex = new PmxVertex();

                vertex.Position = br.ReadVector3();  // 位置
                vertex.Normal   = br.ReadVector3();  // 法線
                vertex.UV       = br.ReadVector2();  // UV

                // 追加UV
                for (var j = 0; j < header.AddUVCound; j++)
                {
                    var uv = br.ReadVector4();
                    if (j == 0)
                    {
                        vertex.UV1 = uv;
                    }
                    if (j == 1)
                    {
                        vertex.UV2 = uv;
                    }
                    if (j == 2)
                    {
                        vertex.UV3 = uv;
                    }
                    if (j == 3)
                    {
                        vertex.UV4 = uv;
                    }
                }

                // ウェイト変形方式
                vertex.WeightType = (PmxVertex.PmxWeightType)br.ReadByte();
                if (vertex.WeightType == PmxVertex.PmxWeightType.BDEF1)
                {
                    vertex.BoneIndex0 = br.ReadFromIndexSize(header.BoneIndexSize);
                }
                else if (vertex.WeightType == PmxVertex.PmxWeightType.BDEF2)
                {
                    vertex.BoneIndex0 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.BoneIndex1 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.Weight0    = br.ReadSingle();
                    vertex.Weight1    = 1.0f - vertex.Weight0;
                }
                else if (vertex.WeightType == PmxVertex.PmxWeightType.BDEF4)
                {
                    vertex.BoneIndex0 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.BoneIndex1 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.BoneIndex2 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.BoneIndex3 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.Weight0    = br.ReadSingle();
                    vertex.Weight1    = br.ReadSingle();
                    vertex.Weight2    = br.ReadSingle();
                    vertex.Weight3    = br.ReadSingle();
                }
                else if (vertex.WeightType == PmxVertex.PmxWeightType.SDEF)
                {
                    vertex.BoneIndex0 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.BoneIndex1 = br.ReadFromIndexSize(header.BoneIndexSize);
                    vertex.Weight0    = br.ReadSingle();
                    vertex.Weight1    = 1.0f - vertex.Weight0;
                    vertex.SDEF_C     = br.ReadVector3();
                    vertex.SDEF_R0    = br.ReadVector3();
                    vertex.SDEF_R1    = br.ReadVector3();
                }

                // エッジ倍率
                vertex.Edge = br.ReadSingle();

                vertList.Vertices[i] = vertex;
            }

            return(vertList);
        }