Example #1
0
 private TriangleEdge[] GetEdges(PMXTriangle tri)
 {
     return(new TriangleEdge[3]
     {
         new TriangleEdge(tri.Vertex1, tri.Vertex2, this._identicalLocation),
         new TriangleEdge(tri.Vertex2, tri.Vertex3, this._identicalLocation),
         new TriangleEdge(tri.Vertex3, tri.Vertex1, this._identicalLocation)
     });
 }
Example #2
0
        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);
            }
        }
Example #3
0
        private bool IsTriangleConnected(PMXTriangle tri, HashSet <TriangleEdge> edgeList)
        {
            TriangleEdge[] edges = GetEdges(tri);
            bool           found = false;

            foreach (TriangleEdge edg in edges)
            {
                if (edgeList.Contains(edg))
                {
                    found = true;
                    break;
                }
            }

            if (found)
            {
                AddEdgesToList(edges, edgeList);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #4
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);
        }
Example #5
0
        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();
            }
        }