コード例 #1
0
        private void CopyMaterialSettings(PMXMaterial baseMat, PMXMaterial newMat)
        {
            newMat.Alpha                  = baseMat.Alpha;
            newMat.Ambient                = baseMat.Ambient;
            newMat.Comment                = baseMat.Comment;
            newMat.Diffuse                = baseMat.Diffuse;
            newMat.DiffuseTexture         = baseMat.DiffuseTexture;
            newMat.DoubleSided            = baseMat.DoubleSided;
            newMat.EdgeColor              = baseMat.EdgeColor;
            newMat.EdgeEnabled            = baseMat.EdgeEnabled;
            newMat.EdgeSize               = baseMat.EdgeSize;
            newMat.GroundShadow           = baseMat.GroundShadow;
            newMat.GroundShadowType       = baseMat.GroundShadowType;
            newMat.NameEN                 = baseMat.NameEN;
            newMat.NameJP                 = baseMat.NameJP;
            newMat.NonStandardToonTexture = baseMat.NonStandardToonTexture;
            newMat.SelfShadow             = baseMat.SelfShadow;
            newMat.SelfShadowPlus         = baseMat.SelfShadowPlus;
            newMat.Specular               = baseMat.Specular;
            newMat.SphereMode             = baseMat.SphereMode;
            newMat.SphereTexture          = baseMat.SphereTexture;
            newMat.StandardToon           = baseMat.StandardToon;
            newMat.StandardToonIndex      = baseMat.StandardToonIndex;
            newMat.VertexColor            = baseMat.VertexColor;

            //Triangles are not being copied!
        }
コード例 #2
0
ファイル: ISMModel.cs プロジェクト: haolink/ISM2Import
        private void ImportTrianglesToMaterial(PMXMaterial mat, int triCount, int triType)
        {
            for (int i = 0; i < triCount; i++)
            {
                PMXVertex vtx1 = null, vtx2 = null, vtx3 = null;
                if (triType == 0x05)
                {
                    vtx1 = pmxModel.Vertices[(int)sp.ReadU16()];
                    vtx2 = pmxModel.Vertices[(int)sp.ReadU16()];
                    vtx3 = pmxModel.Vertices[(int)sp.ReadU16()];
                }
                else
                {
                    vtx1 = pmxModel.Vertices[sp.ReadS32()];
                    vtx2 = pmxModel.Vertices[sp.ReadS32()];
                    vtx3 = pmxModel.Vertices[sp.ReadS32()];
                }

                PMXTriangle tri = new PMXTriangle(pmxModel, vtx1, vtx2, vtx3);
                mat.Triangles.Add(tri);
            }
        }
コード例 #3
0
        private List <PMXMaterial> SplitTriangles(PMXMaterial mat)
        {
            int[] matIndex = new int[mat.Triangles.Count];
            int   i, j, mI;
            int   addedTriangles;

            for (i = 0; i < matIndex.Length; i++)
            {
                matIndex[i] = -1;
            }

            mI = -1;
            int outInfo = 0;
            HashSet <TriangleEdge> edgesInPart;

            for (i = 0; i < matIndex.Length; i++)
            {
                int cIndex = matIndex[i];
                if (cIndex >= 0)
                {
                    continue;
                }

                if (i >= outInfo)
                {
                    Console.WriteLine(i + " / " + matIndex.Length);
                    while (i >= outInfo)
                    {
                        outInfo += 250;
                    }
                }

                mI++;
                matIndex[i] = mI;
                edgesInPart = new HashSet <TriangleEdge>();
                AddEdgesToList(GetEdges(mat.Triangles[i]), edgesInPart);

                do
                {
                    addedTriangles = 0;
                    for (j = i + 1; j < matIndex.Length; j++)
                    {
                        if (matIndex[j] >= 0)
                        {
                            continue;
                        }

                        PMXTriangle tri = mat.Triangles[j];
                        if (IsTriangleConnected(tri, edgesInPart))
                        {
                            matIndex[j] = mI;
                            addedTriangles++;
                        }
                    }
                } while (addedTriangles > 0);
            }

            List <PMXTriangle>[] triangleGroups = new List <PMXTriangle> [mI + 1];
            for (i = 0; i <= mI; i++)
            {
                triangleGroups[i] = new List <PMXTriangle>();
            }
            for (i = 0; i < matIndex.Length; i++)
            {
                PMXTriangle tri = mat.Triangles[i];
                triangleGroups[matIndex[i]].Add(tri);
            }

            PMXMaterial restMaterial = new PMXMaterial(this._model);

            CopyMaterialSettings(mat, restMaterial);

            List <PMXMaterial> newMaterials = new List <PMXMaterial>();
            int resIndex = 0;

            foreach (List <PMXTriangle> triangleGroup in triangleGroups)
            {
                if (triangleGroup.Count < 10 && this._ignoreSmallParts)
                {
                    restMaterial.Triangles.AddRange(triangleGroup);
                    continue;
                }

                resIndex++;
                PMXMaterial nm = new PMXMaterial(this._model);
                CopyMaterialSettings(mat, nm);
                nm.NameEN = nm.NameEN + " " + resIndex.ToString();
                nm.NameJP = nm.NameJP + " " + resIndex.ToString();
                nm.Triangles.AddRange(triangleGroup);

                newMaterials.Add(nm);
            }

            if (restMaterial.Triangles.Count > 0)
            {
                restMaterial.NameEN = restMaterial.NameEN + " Rest";
                restMaterial.NameJP = restMaterial.NameJP + " Rest";
                newMaterials.Add(restMaterial);
            }

            return(newMaterials);
        }
コード例 #4
0
ファイル: ISMModel.cs プロジェクト: haolink/ISM2Import
        private ISMModel(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);

            sp = new StreamParser(fs, Endian.Little);

            pmxModel = new PMXModel();

            sp.BaseStream.Seek(0x00, SeekOrigin.Begin);

            if (sp.ReadU32() != 0x324D5349)
            {
                fs.Close();
                return;
            }

            sp.BaseStream.Seek(0x14, SeekOrigin.Begin);

            uint endianCheck = sp.ReadU32();

            if (endianCheck > 0 && endianCheck < 65535)
            {
                sp.Endian = Endian.Little;
            }
            else
            {
                sp.Endian = Endian.Big;
            }

            sp.BaseStream.Seek(0x04, SeekOrigin.Begin);
            versionA = sp.ReadU8();
            byte VersionB     = sp.ReadU8();
            byte VersionC     = sp.ReadU8();
            byte VersionD     = sp.ReadU8();
            uint header3      = sp.ReadU32();
            uint header4      = sp.ReadU32();
            uint filesize     = sp.ReadU32();
            uint sectionCount = sp.ReadU32();
            uint header7      = sp.ReadU32();
            uint header8      = sp.ReadU32();

            int i, j, k;

            SectionData[] SectionArray = new SectionData[sectionCount];
            for (i = 0; i < sectionCount; i++)
            {
                SectionArray[i] = new SectionData()
                {
                    SectionType   = sp.ReadU32(),
                    SectionOffset = sp.ReadU32()
                };
            }


            /**
             * Importing strings begin
             */
            foreach (SectionData sd in SectionArray)
            {
                if (sd.SectionType == 33) //String array needs to be filled first
                {
                    sp.BaseStream.Seek(sd.SectionOffset + 8, SeekOrigin.Begin);
                    int stringCount = sp.ReadS32();
                    stringArray = new string[stringCount];
                    uint[] strOffsets = new uint[stringCount];

                    for (i = 0; i < stringCount; i++)
                    {
                        strOffsets[i] = sp.ReadU32();
                    }

                    for (i = 0; i < stringCount; i++)
                    {
                        sp.BaseStream.Seek(strOffsets[i], SeekOrigin.Begin);
                        stringArray[i] = sp.ReadAnsiNullTerminatedString();
                    }
                }
            }

            /**
             * Importing strings end
             */


            /**
             *  Materials
             */
            foreach (SectionData sd in SectionArray)
            {
                if (sd.SectionType == 97)
                {
                    sp.BaseStream.Seek(sd.SectionOffset + 8, SeekOrigin.Begin);
                    int    matTotal       = sp.ReadS32();
                    uint[] matOffsetArray = new uint[matTotal];
                    for (i = 0; i < matTotal; i++)
                    {
                        matOffsetArray[i] = sp.ReadU32();
                    }

                    for (i = 0; i < matTotal; i++)
                    {
                        sp.BaseStream.Seek(matOffsetArray[i] + 8, SeekOrigin.Begin);
                        int    matSubTotal   = sp.ReadS32();
                        string matSubString1 = stringArray[sp.ReadS32()];
                        string matSubString2 = stringArray[sp.ReadS32()];
                        string matSubString3 = stringArray[sp.ReadS32()];
                        sp.BaseStream.Seek(4, SeekOrigin.Current);

                        PMXMaterial mat = new PMXMaterial(pmxModel);
                        pmxModel.Materials.Add(mat);
                        mat.NameEN            = matSubString1;
                        mat.NameJP            = matSubString1;
                        mat.Diffuse           = new PMXColorRGB(0.77f, 0.77f, 0.77f);
                        mat.Specular          = new PMXColorRGB(0.0f, 0.0f, 0.0f);
                        mat.Ambient           = new PMXColorRGB(1.0f, 1.0f, 1.0f);
                        mat.StandardToonIndex = 3;
                        mat.EdgeEnabled       = false;

                        if (matSubTotal > 0)
                        {
                            int matSubOffset = sp.ReadS32();
                            sp.BaseStream.Seek(matSubOffset + 12, SeekOrigin.Begin);
                            matSubOffset = sp.ReadS32();
                            sp.BaseStream.Seek(matSubOffset + 20, SeekOrigin.Begin);
                            matSubOffset = sp.ReadS32();
                            sp.BaseStream.Seek(matSubOffset + 24, SeekOrigin.Begin);
                            matSubOffset = sp.ReadS32();
                            sp.BaseStream.Seek(matSubOffset + 24, SeekOrigin.Begin);
                            matSubOffset = sp.ReadS32();
                            sp.BaseStream.Seek(matSubOffset, SeekOrigin.Begin);
                            mat.DiffuseTexture = stringArray[sp.ReadS32()] + ".dds";
                        }
                        else
                        {
                            mat.DiffuseTexture = "tex_c.dds";
                        }


                        //Console.WriteLine(texturename);
                    }
                }
            }

            /**
             *  Bones and material groups
             */
            foreach (SectionData sd in SectionArray)
            {
                if (sd.SectionType == 03)
                {
                    Console.WriteLine("Object data");
                    sp.BaseStream.Seek(sd.SectionOffset + 8, SeekOrigin.Begin);
                    int    boneCount   = sp.ReadS32();
                    uint[] boneOffsets = new uint[boneCount];

                    string boneDataString1 = stringArray[sp.ReadS32()];
                    string boneDataString2 = stringArray[sp.ReadS32()];

                    for (i = 0; i < boneCount; i++)
                    {
                        boneOffsets[i] = sp.ReadU32();
                    }

                    for (i = 0; i < boneCount; i++)
                    {
                        sp.BaseStream.Seek(boneOffsets[i] + 8, SeekOrigin.Begin);

                        /*uint sectionType = sp.ReadU32();
                         * sp.ReadU32();*/
                        int    boneHeaderTotal = sp.ReadS32();
                        string boneName1       = stringArray[sp.ReadS32()];
                        string boneName2       = stringArray[sp.ReadS32()];
                        sp.BaseStream.Seek(8, SeekOrigin.Current);
                        uint boneParentOffset = sp.ReadU32();
                        int  boneParent       = -1;
                        for (j = 0; j < boneCount; j++)
                        {
                            if (boneOffsets[j] == boneParentOffset)
                            {
                                boneParent = j;
                            }
                        }
                        sp.BaseStream.Seek(12, SeekOrigin.Current);
                        int boneIdNum = sp.ReadS32();
                        sp.BaseStream.Seek(16, SeekOrigin.Current);

                        uint[] boneHeaderOffsets = new uint[boneHeaderTotal];

                        for (j = 0; j < boneHeaderTotal; j++)
                        {
                            boneHeaderOffsets[j] = sp.ReadU32();
                        }

                        for (j = 0; j < boneHeaderTotal; j++)
                        {
                            sp.BaseStream.Seek(boneHeaderOffsets[j], SeekOrigin.Begin);
                            uint sectionType = sp.ReadU32();

                            if (sectionType == 76)
                            {
                                ImportSurface();
                            }
                            if (sectionType == 91)
                            {
                                ImportBone(boneName1, i, boneParent, boneIdNum);
                            }
                        }
                    }
                }
            }


            /**
             * Importing textures begin
             */
            /*foreach (SectionData sd in SectionArray)
             * {
             *  if (sd.SectionType == 46)
             *  {
             *      sp.BaseStream.Seek(sd.SectionOffset + 8, SeekOrigin.Begin);
             *      int texTotal = sp.ReadS32();
             *      uint[] texOffsetArray = new uint[texTotal];
             *      for (i = 0; i < texTotal; i++)
             *      {
             *          texOffsetArray[i] = sp.ReadU32();
             *      }
             *
             *      for (i = 0; i < texTotal; i++)
             *      {
             *          sp.BaseStream.Seek(texOffsetArray[i] + 12, SeekOrigin.Begin);
             *          string texturename = stringArray[sp.ReadS32()];
             *          sp.BaseStream.Seek(12, SeekOrigin.Current);
             *          //Console.WriteLine(texturename);
             *      }
             *  }
             * }*/
            //TODO: Not sure what these do

            /**
             * Importing strings end
             */

            /**
             * Vertices
             */
            foreach (SectionData sd in SectionArray)
            {
                if (sd.SectionType == 11)
                {
                    Console.WriteLine("Vertex data");
                    sp.BaseStream.Seek(sd.SectionOffset + 8, SeekOrigin.Begin);
                    int vtxHeaderTotal = sp.ReadS32();

                    uint[] vtxHeadOffsets = new uint[vtxHeaderTotal];
                    for (i = 0; i < vtxHeaderTotal; i++)
                    {
                        vtxHeadOffsets[i] = sp.ReadU32();
                    }

                    for (i = 0; i < vtxHeaderTotal; i++)
                    {
                        sp.BaseStream.Seek(vtxHeadOffsets[i], SeekOrigin.Begin);
                        uint sectionType = sp.ReadU32();
                        if (sectionType == 10)
                        {
                            ImportVertexGroup();
                        }
                    }
                }
            }

            fs.Close();
        }
コード例 #5
0
ファイル: GsmdlFile.cs プロジェクト: haolink/VVVPMX
        private void loadMeshs()
        {
            int i, j, k, l, m;

            int vtxIndex = 0;

            for (i = 0; i < this.mdlInfo.Count7; i++)
            {
                long vtxBase   = this.vertBase + this.meshInfoList[i].vtxBufferStart;
                long idxBase   = this.faceBase + this.meshInfoList[i].idxBufferStart;
                uint vtxStride = this.meshInfoList[i].vtxStride;
                //Console.WriteLine(vtxStride);
                uint      matBase = this.meshInfoList[i].meshId;
                FvfInfo[] fvfInfo = this.fvfList[i];

                this.fs.Seek(this.boneMapStart + this.meshInfoList[i].bonePalletStart * 2, SeekOrigin.Begin);
                List <ushort> bonePallet = new List <ushort>();
                for (j = 0; j < this.meshInfoList[i].bonePalletCount; j++)
                {
                    bonePallet.Add(br.ReadUInt16());
                }

                for (j = 0; j < this.meshInfoList[i].meshCount; j++)
                {
                    PMXMaterial mat = new PMXMaterial(this.pmx);
                    mat.Diffuse.R         = 0.77f;
                    mat.Diffuse.G         = 0.77f;
                    mat.Diffuse.B         = 0.77f;
                    mat.Specular.R        = 0.0f;
                    mat.Specular.G        = 0.0f;
                    mat.Specular.B        = 0.0f;
                    mat.Ambient.R         = 0.5f;
                    mat.Ambient.G         = 0.5f;
                    mat.Ambient.B         = 0.5f;
                    mat.EdgeEnabled       = false;
                    mat.EdgeSize          = 0.0f;
                    mat.StandardToonIndex = 3;

                    string meshname = this.matInfoList[i].MeshName;

                    if (this.matNames != null && matNames.Count > 0)
                    {
                        meshname = this.matNames[(int)this.meshInfoList[i].matID] + "_" + i.ToString() + "_" + j.ToString();
                    }

                    mat.NameJP = meshname;
                    mat.NameEN = meshname;

                    MaterialInfo matInfo = this.matInfoList[(int)(matBase + j)];

                    if (matInfo.Lod != 1 && matInfo.Lod != -1)
                    {
                        continue;
                    }

                    this.fs.Seek(idxBase, SeekOrigin.Begin);
                    List <int> idxTmp = new List <int>();
                    for (l = 0; l < matInfo.FaceCount; l++)
                    {
                        if (meshInfoList[i].idxType == 2)
                        {
                            idxTmp.Add((int)(this.br.ReadUInt32() - matInfo.FaceStart));
                        }
                        else
                        {
                            idxTmp.Add((int)(this.br.ReadUInt16() - matInfo.FaceStart));
                        }
                    }
                    idxBase = this.fs.Position;


                    this.fs.Seek(vtxBase + vtxStride * matInfo.FaceStart, SeekOrigin.Begin);
                    long vtxPosition = this.fs.Position;

                    List <PMXVertex> vertices = new List <PMXVertex>();

                    for (k = 0; k < matInfo.VertCount; k++)
                    {
                        PMXVertex vtx = new PMXVertex(this.pmx);
                        byte[]    idx = new byte[4] {
                            0, 0, 0, 0
                        };
                        byte[] wgt = new byte[4] {
                            0, 0, 0, 0
                        };

                        for (l = 0; l < fvfInfo.Length; l++)
                        {
                            this.fs.Seek(vtxPosition + k * vtxStride + fvfInfo[l].fvfPos, SeekOrigin.Begin);
                            switch (fvfInfo[l].compType)
                            {
                            case 0:
                                vtx.Position.X = this.br.ReadSingle() * SCALE;
                                vtx.Position.Y = this.br.ReadSingle() * SCALE;
                                vtx.Position.Z = this.br.ReadSingle() * SCALE * (-1);
                                break;

                            case 2:
                                vtx.Normals.X = this.br.ReadSingle();
                                vtx.Normals.Y = this.br.ReadSingle();
                                vtx.Normals.Z = this.br.ReadSingle() * (-1);
                                break;

                            case 8:
                                vtx.UV.U = this.br.ReadSingle();
                                vtx.UV.V = this.br.ReadSingle();
                                break;

                            case 7:
                                for (m = 0; m < 4; m++)
                                {
                                    idx[m] = this.br.ReadByte();
                                }
                                break;

                            case 1:
                                for (m = 0; m < 4; m++)
                                {
                                    wgt[m] = this.br.ReadByte();
                                }
                                break;
                            }
                        }

                        int totalWeight = 0;
                        Dictionary <ushort, int> weights = new Dictionary <ushort, int>();
                        for (m = 0; m < 4; m++)
                        {
                            byte bi = idx[m];
                            if (bi >= bonePallet.Count)
                            {
                                continue;
                            }
                            ushort bni = bonePallet[bi];

                            int weight = 0;
                            if (weights.ContainsKey(bni))
                            {
                                weight = weights[bni];
                            }
                            byte cw = wgt[m];

                            totalWeight += cw;
                            weight      += cw;
                            weights[bni] = weight;
                        }

                        if (weights.Count == 1)
                        {
                            PMXVertexDeformBDEF1 b1 = new PMXVertexDeformBDEF1(this.pmx, vtx);
                            b1.Bone1   = this.pmx.Bones[weights.Keys.First()];
                            vtx.Deform = b1;
                        }
                        else
                        {
                            List <KeyValuePair <ushort, int> > weightList = weights.ToList();
                            weightList.Sort(delegate(KeyValuePair <ushort, int> pair1, KeyValuePair <ushort, int> pair2)
                            {
                                return(pair2.Value.CompareTo(pair1.Value));
                            });

                            for (m = 3; m >= 1; m--)
                            {
                                if (weightList.Count > m && weightList[m].Value == 0)
                                {
                                    weightList.RemoveAt(m);
                                }
                            }

                            if (weightList.Count == 1)
                            {
                                PMXVertexDeformBDEF1 b1 = new PMXVertexDeformBDEF1(this.pmx, vtx);
                                b1.Bone1   = this.pmx.Bones[weightList[0].Key];
                                vtx.Deform = b1;
                            }
                            else if (weightList.Count == 2)
                            {
                                PMXVertexDeformBDEF2 b2 = new PMXVertexDeformBDEF2(this.pmx, vtx);
                                b2.Bone1       = this.pmx.Bones[weightList[0].Key];
                                b2.Bone1Weight = (float)weightList[0].Value / (float)totalWeight;
                                b2.Bone2       = this.pmx.Bones[weightList[1].Key];
                                vtx.Deform     = b2;
                            }
                            else if (weightList.Count > 2)
                            {
                                PMXVertexDeformBDEF4 b4 = new PMXVertexDeformBDEF4(this.pmx, vtx);
                                b4.Bone1       = this.pmx.Bones[weightList[0].Key];
                                b4.Bone1Weight = (float)weightList[0].Value / (float)totalWeight;
                                b4.Bone2       = this.pmx.Bones[weightList[1].Key];
                                b4.Bone2Weight = (float)weightList[1].Value / (float)totalWeight;
                                b4.Bone3       = this.pmx.Bones[weightList[2].Key];
                                b4.Bone3Weight = (float)weightList[2].Value / (float)totalWeight;
                                if (weightList.Count < 4)
                                {
                                    b4.Bone4 = null;
                                }
                                else
                                {
                                    b4.Bone4       = this.pmx.Bones[weightList[3].Key];
                                    b4.Bone4Weight = (float)weightList[3].Value / (float)totalWeight;
                                }
                                vtx.Deform = b4;
                            }
                            else
                            {
                                //Most likely a prop!
                                //Console.WriteLine("Weight error on " + this.inFile);
                                if (pmx.Bones.Count == 0)
                                {
                                    PMXBone mb = new PMXBone(pmx);
                                    mb.NameEN       = "prop";
                                    mb.NameJP       = "prop";
                                    mb.Position     = new PMXVector3(0, 0, 0);
                                    mb.Translatable = true;
                                    pmx.Bones.Add(mb);
                                }
                                PMXVertexDeformBDEF1 b1 = new PMXVertexDeformBDEF1(this.pmx, vtx);
                                b1.Bone1   = this.pmx.Bones[0];
                                vtx.Deform = b1;
                            }
                        }

                        vertices.Add(vtx);
                        this.pmx.Vertices.Add(vtx);
                        vtxIndex++;
                    }


                    for (k = 0; k < idxTmp.Count; k += 3)
                    {
                        PMXTriangle tri = new PMXTriangle(this.pmx);
                        tri.Vertex1 = vertices[idxTmp[k + 2]];
                        tri.Vertex2 = vertices[idxTmp[k + 1]];
                        tri.Vertex3 = vertices[idxTmp[k + 0]];
                        mat.Triangles.Add(tri);
                    }
                    this.pmx.Materials.Add(mat);
                }
            }

            this.totalVertCount = (uint)vtxIndex;

            if (this.mdlInfo.hasExp == 0)
            {
                this.WritePMX();
            }
            else
            {
                this.CheckForVertexMorphs();
            }
        }